/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2016, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.gce.imagepyramid; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.color.ColorSpace; import java.awt.image.RenderedImage; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.text.ParseException; import java.util.Arrays; import java.util.Properties; import org.apache.commons.io.filefilter.FileFilterUtils; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.data.DataUtilities; import org.geotools.factory.Hints; import org.geotools.geometry.GeneralEnvelope; import org.geotools.referencing.CRS; import org.geotools.test.TestData; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.opengis.coverage.grid.GridEnvelope; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.parameter.GeneralParameterValue; import org.opengis.parameter.InvalidParameterValueException; import org.opengis.parameter.ParameterValue; import org.opengis.referencing.NoSuchAuthorityCodeException; import it.geosolutions.imageio.utilities.ImageIOUtilities; /** * Test the resolutionLevel-to-ImageMosaicReader mapping machinery. */ public class ImageLevelsMapperTest extends Assert { protected static final Double DELTA = 1E-6; @Before public void init() { System.setProperty("org.geotools.referencing.forceXY","true"); CRS.reset("all"); } @AfterClass public static void close() { System.clearProperty("org.geotools.referencing.forceXY"); CRS.reset("all"); } @Test public void multicoveragePyramidWithOverviews() throws IOException, MismatchedDimensionException, NoSuchAuthorityCodeException, InvalidParameterValueException, ParseException { // // Get the resource. // final URL testFile = TestData.getResource(this, "multipyramidwithoverviews"); File mosaicFolder = DataUtilities.urlToFile(testFile); assertNotNull(testFile); File[] pyramidLevels = mosaicFolder.listFiles((FileFilter) FileFilterUtils .directoryFileFilter()); for (File pyramidLevel : pyramidLevels) { cleanFiles(pyramidLevel); } cleanFiles(mosaicFolder); // // Get the reader // final ImagePyramidReader reader = new ImagePyramidReader(testFile); assertNotNull(reader); assertEquals(2, reader.getGridCoverageCount()); String coverageNames[] = reader.getGridCoverageNames(); Arrays.sort(coverageNames); assertEquals("gray", coverageNames[0]); assertEquals("rgb", coverageNames[1]); // // Get the coverage // GridCoverage2D coverage = (GridCoverage2D) reader.read(coverageNames[0], null); assertNotNull(coverage); RenderedImage renderedImage = coverage.getRenderedImage(); int colorSpaceType = renderedImage.getColorModel().getColorSpace().getType(); assertEquals(ColorSpace.TYPE_GRAY, colorSpaceType); GridEnvelope gridEnvelope = coverage.getGridGeometry().getGridRange(); assertEquals(64, gridEnvelope.getSpan(0), DELTA); assertEquals(64, gridEnvelope.getSpan(1), DELTA); // Read a reduced view of the RGB coverage final ParameterValue<GridGeometry2D> gg = AbstractGridFormat.READ_GRIDGEOMETRY2D .createValue(); final GeneralEnvelope envelope = reader.getOriginalEnvelope(); GridEnvelope2D gridRange = new GridEnvelope2D(((GridEnvelope2D)reader.getOriginalGridRange()).getBounds()); final Dimension dim = new Dimension(); dim.setSize(gridRange.getSpan(0) / 16.0, gridRange.getSpan(1) / 16.0); Rectangle rasterArea = ((GridEnvelope2D) gridRange); rasterArea.setSize(dim); GridEnvelope2D range = new GridEnvelope2D(rasterArea); gg.setValue(new GridGeometry2D(range, envelope)); coverage = (GridCoverage2D) reader.read(coverageNames[1], new GeneralParameterValue[] { gg }); assertNotNull(coverage); renderedImage = coverage.getRenderedImage(); colorSpaceType = renderedImage.getColorModel().getColorSpace().getType(); assertEquals(ColorSpace.TYPE_RGB, colorSpaceType); gridEnvelope = coverage.getGridGeometry().getGridRange(); assertEquals(4, gridEnvelope.getSpan(0), DELTA); assertEquals(4, gridEnvelope.getSpan(1), DELTA); // test on expanded Envelope (Double the size of the envelope) final GeneralEnvelope doubleEnvelope = new GeneralEnvelope(new double[] { envelope.getLowerCorner().getOrdinate(0), envelope.getLowerCorner().getOrdinate(1) }, new double[] { envelope.getLowerCorner().getOrdinate(0) + envelope.getSpan(0) * 2, envelope.getLowerCorner().getOrdinate(1) + envelope.getSpan(1) * 2 }); doubleEnvelope.setCoordinateReferenceSystem(envelope.getCoordinateReferenceSystem()); GridEnvelope doubleRange = reader.getOriginalGridRange(); dim.setSize(doubleRange .getSpan(0) * 2, doubleRange .getSpan(1) * 2); rasterArea = ((GridEnvelope2D) doubleRange ); rasterArea.setSize(dim); range = new GridEnvelope2D(rasterArea); gg.setValue(new GridGeometry2D(doubleRange , doubleEnvelope)); coverage = ((GridCoverage2D) reader.read( coverageNames[1], new GeneralParameterValue[] { gg })); assertNotNull(coverage); renderedImage = coverage.getRenderedImage(); gridEnvelope = coverage.getGridGeometry().getGridRange(); assertEquals(64, gridEnvelope.getSpan(0), DELTA); assertEquals(64, gridEnvelope.getSpan(1), DELTA); // Check the levels mapping Properties properties = new Properties(); File propertyFile = new File(mosaicFolder, "multipyramidwithoverviews.properties"); // Test image levels mapping on the newly created pyramid properties file FileInputStream fis = null; ImageLevelsMapper mapper = null; final double baseRes = 0.4287193d; try { fis = new FileInputStream(propertyFile); properties.load(fis); mapper = new ImageLevelsMapper(properties); assertEquals(5, mapper.getNumOverviews()); String[] levelDirs = mapper.getLevelsDirs(); assertNotNull(levelDirs); assertEquals(2, levelDirs.length); assertEquals("0", levelDirs[0]); assertEquals("1", levelDirs[1]); double[] highRes = mapper.getHighestResolution(); assertNotNull(highRes); match(new double[] { baseRes, baseRes }, highRes); double[][] resolutions = mapper.getOverViewResolutions(); assertNotNull(resolutions); match(new double[] { baseRes * 2, baseRes * 2 }, resolutions[0]); match(new double[] { baseRes * 4, baseRes * 4 }, resolutions[1]); match(new double[] { baseRes * 8, baseRes * 8 }, resolutions[2]); match(new double[] { baseRes * 16, baseRes * 16 }, resolutions[3]); match(new double[] { baseRes * 32, baseRes * 32 }, resolutions[4]); assertEquals(0, mapper.getImageReaderIndex(0)); assertEquals(0, mapper.getImageReaderIndex(1)); assertEquals(1, mapper.getImageReaderIndex(2)); assertEquals(1, mapper.getImageReaderIndex(3)); assertEquals(1, mapper.getImageReaderIndex(4)); assertEquals(1, mapper.getImageReaderIndex(5)); } finally { if (fis != null) { try { fis.close(); } catch(Throwable t) { // Ignore it } } mapper.dispose(); } } private void match(double[] expected, double[] actual) { assertEquals(expected[0], actual[0], DELTA); assertEquals(expected[1], actual[1], DELTA); } protected void cleanFiles(File mosaicFolder) { for (File configFile : mosaicFolder.listFiles((FileFilter) FileFilterUtils.or( FileFilterUtils.suffixFileFilter("db"), FileFilterUtils .suffixFileFilter("sample_image"), FileFilterUtils.and(FileFilterUtils .suffixFileFilter(".properties"), FileFilterUtils .notFileFilter(FileFilterUtils.or( FileFilterUtils.nameFileFilter("indexer.properties"), FileFilterUtils.nameFileFilter("datastore.properties"))))))) { configFile.delete(); } } }