/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2016, 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.metadata.geotiff; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.util.List; import javax.imageio.IIOImage; import javax.imageio.metadata.IIOMetadataNode; import org.opengis.metadata.spatial.PixelOrientation; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.util.FactoryException; import org.opengis.util.GenericName; import org.apache.sis.internal.referencing.GeodeticObjectBuilder; import org.apache.sis.measure.NumberRange; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.NamedIdentifier; import org.geotoolkit.coverage.Category; import org.geotoolkit.coverage.GridSampleDimension; import org.geotoolkit.image.internal.ImageUtils; import org.geotoolkit.image.internal.SampleType; import org.geotoolkit.image.io.metadata.ReferencingBuilder; import org.geotoolkit.image.io.metadata.SpatialMetadata; import org.geotoolkit.image.io.metadata.SpatialMetadataFormat; import org.geotoolkit.image.io.plugin.IIOTiffMetadata; import org.geotoolkit.image.io.plugin.TiffImageReader; import org.geotoolkit.image.io.plugin.TiffImageWriter; import org.geotoolkit.internal.image.io.DimensionAccessor; import org.geotoolkit.internal.image.io.GridDomainAccessor; import org.geotoolkit.metadata.Citations; import org.junit.After; import org.junit.Test; import static org.junit.Assert.*; import static org.geotoolkit.metadata.geotiff.GeoTiffConstants.TAG_GEOTIFF_IFD; /** * Test class to improve Reading / writing action with some geographicales or related metadatas fonctionalities.<br> * Moreover don't verify generated image pertinency, other Image reader / writer tests improve these comportements it is not the aim of it. * * @author Remi Marechal (Geomatys). */ public class GeotiffTest extends org.geotoolkit.test.TestBase { /** * Temporary directory where test file are written. */ private final File directory; /** * Needed writer to test multiple no Data writing. */ private final TiffImageWriter writer = new TiffImageWriter(null); /** * Needed Reader to test multiple no Data reading. */ private final TiffImageReader reader = new TiffImageReader(null); public GeotiffTest() throws IOException { directory = new File(System.getProperty("java.io.tmpdir")+"/geotiffTest/"); directory.mkdirs(); } /** * Close Reader / Writer. */ @After public void close() { writer.dispose(); reader.dispose(); cleanFiles(); } /** * Improve Reader / Writer to write and read multiple noData values. * Test noData with 2 values out of sample interval boundary, * 2 values on sample boundary interval border, and a value which intersect interval. * We expect 5 saved nodata categories and to sample boundaries categories. * In our case : nodata : {0, 1, 128, 254, 255}, sample interval : [0 ; 255] (Byte space) * Expected 7 categories : [0 ; 0], [1 ; 1], ]1 ; 128[, [128 ; 128], ]128 ; 254[, [254 ; 254], [255 ; 255] in ascending order. * @throws java.io.IOException if problem during reading writing action. */ @Test public void noDataTest() throws IOException { final RenderedImage testedImg = ImageUtils.createScaledInterleavedImage(2, 2, SampleType.BYTE, 3); final IIOMetadataNode root = new IIOMetadataNode(TAG_GEOTIFF_IFD); final GeoTiffMetaDataStack stack = new GeoTiffMetaDataStack(root); stack.setMinSampleValue(1, 1, 1); stack.setMaxSampleValue(254, 254, 254); stack.setNoData("0.0"); stack.setNoData("1.0"); stack.setNoData("128.0"); stack.setNoData("254.0"); stack.setNoData("255.0"); stack.flush(); final File filTest = File.createTempFile("multipleNodata", "tiff", directory); filTest.mkdirs(); writer.setOutput(filTest); final IIOImage img = new IIOImage(testedImg, null, new IIOTiffMetadata(root)); writer.write(img); writer.dispose(); reader.setInput(filTest); SpatialMetadata sm = reader.getImageMetadata(0); reader.dispose(); final DimensionAccessor dimAccess = new DimensionAccessor(sm); final List<GridSampleDimension> sDim = dimAccess.getGridSampleDimensions(); assertEquals("gridSampleDimension number", 3, sDim.size()); final GridSampleDimension gsd = sDim.get(0); final List<Category> categories = gsd.getCategories(); assertEquals("categories number", 7, categories.size()); //-- expected number range array //-- [0 ; 0], [1 ; 1], ]1 ; 128[, [128 ; 128], ]128 ; 254[, [254 ; 254], [255 ; 255] //-- in category specification all getted value are inclusive //-- expected array become : final double[] expectedArray = new double[]{0, 0, //-- 7 categories 1, 1, 2, 127, 128, 128, 129, 253, 254, 254, 255, 255}; final double[] foundArray = new double[14]; int fAId = 0; for (final Category cat : categories) { final NumberRange r = cat.getRange(); foundArray[fAId++] = r.getMinDouble(true); foundArray[fAId++] = r.getMaxDouble(true); } assertArrayEquals(expectedArray, foundArray, 1E-12); } /** * Improve Reader / Writer to write and read date in tiff format. * * @throws IOException if problem during */ @Test public void temporalTest() throws IOException, FactoryException { final RenderedImage testedImg = ImageUtils.createScaledInterleavedImage(2, 2, SampleType.BYTE, 3); //-- temporal CRS final NamedIdentifier name = new NamedIdentifier(Citations.CRS, "TemporalReferenceSystem"); final CoordinateReferenceSystem crsSource = new GeodeticObjectBuilder().addName((GenericName) name) .createCompoundCRS(CommonCRS.WGS84.geographic(), CommonCRS.Temporal.JAVA.crs()); final SpatialMetadata sm = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(SpatialMetadataFormat.GEOTK_FORMAT_NAME)); final ReferencingBuilder builder = new ReferencingBuilder(sm); builder.setCoordinateReferenceSystem(crsSource); final long time = System.currentTimeMillis(); final double[] origin = new double[]{-45, -45, time}; final double[] envMax = new double[]{45, 45, System.currentTimeMillis()}; final int[] high = new int[]{1, 1, 1}; final GridDomainAccessor accessor = new GridDomainAccessor(sm); accessor.setRectifiedGridDomain(origin, envMax, null, high, null, false); accessor.setSpatialRepresentation(origin, envMax, null, PixelOrientation.UPPER_LEFT); final File filTest = File.createTempFile("dateTest", "tiff", directory); filTest.mkdirs(); writer.setOutput(filTest); final IIOImage img = new IIOImage(testedImg, null, sm); writer.write(img); writer.dispose(); reader.setInput(filTest); SpatialMetadata readerMeth = reader.getImageMetadata(0); reader.dispose(); final GridDomainAccessor gda = new GridDomainAccessor(readerMeth); final double[] outDate = gda.getAttributeAsDoubles("origin", false); //-- date truncated at second and time exprimate in milli second //-- tolerance at 1000 to avoid milli second from truncature. assertEquals(time, outDate[2], 1E3); } /** * Clean temporary directory from generated files test. */ private final void cleanFiles() { for (File f : directory.listFiles()) { if (f.exists()) f.delete(); } directory.delete(); } }