/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2015, 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.coverage.grid; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import it.geosolutions.jaiext.range.NoDataContainer; import it.geosolutions.jaiext.range.Range; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.IOException; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; import javax.media.jai.BorderExtender; import javax.media.jai.Interpolation; import javax.media.jai.PlanarImage; import javax.media.jai.ROIShape; import org.geotools.coverage.CoverageFactoryFinder; import org.geotools.factory.Hints; import org.geotools.referencing.operation.matrix.XAffineTransform; import org.geotools.resources.coverage.CoverageUtilities; import org.junit.Before; import org.junit.Test; import org.opengis.coverage.grid.GridEnvelope; import org.opengis.geometry.Envelope; /** * Tests the {@link Interpolator2D} implementation. * * * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) */ public final class InterpolatorTest extends GridCoverageTestBase { /** * The interpolators to use. */ private Interpolation[] interpolations; /** Used to avoid errors if building on a system where hostname is not defined */ private boolean hostnameDefined; /** * Setup the {@linkplain #interpolations} values. */ @Before public void setup() { final int[] types = { Interpolation.INTERP_BICUBIC, Interpolation.INTERP_BILINEAR, Interpolation.INTERP_NEAREST }; interpolations = new Interpolation[types.length]; for (int i=0; i<interpolations.length; i++) { interpolations[i] = Interpolation.getInstance(types[i]); } try { InetAddress.getLocalHost(); hostnameDefined = true; } catch (Exception ex) { hostnameDefined = false; } } /** * Tests bilinear intersection at pixel edges. It should be equals * to the average of the four pixels around. */ @Test public void testInterpolationAtEdges() { // Following constant is pixel size (in degrees). // This constant must be identical to the one defined in 'getRandomCoverage()' GridCoverage2D coverage = getRandomCoverage(); final double PIXEL_SIZE = XAffineTransform.getScale((AffineTransform) ((GridGeometry2D)coverage.getGridGeometry()).getGridToCRS()); final Interpolation interpolation = Interpolation.getInstance(Interpolation.INTERP_BILINEAR); coverage = Interpolator2D.create(coverage, new Interpolation[] {interpolation}); final int band = 0; // Band to test. double[] buffer = null; final BorderExtender be = BorderExtender.createInstance(BorderExtender.BORDER_COPY); Rectangle rectangle = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getBounds(); rectangle = new Rectangle(rectangle.x,rectangle.y,rectangle.width+interpolation.getWidth(), rectangle.height+interpolation.getHeight()); final Raster data = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getExtendedData(rectangle,be); final Envelope envelope = coverage.getEnvelope(); final GridEnvelope range = coverage.getGridGeometry().getGridRange(); final double left = envelope.getMinimum(0); final double upper = envelope.getMaximum(1); final Point2D.Double point = new Point2D.Double(); // Will maps to pixel upper-left corner for (int j=range.getSpan(1); j>=0;--j) { for (int i=range.getSpan(0); i>=0;--i) { point.x = left + PIXEL_SIZE*i; point.y = upper - PIXEL_SIZE*j; buffer = coverage.evaluate(point, buffer); double t = buffer[band]; // Computes the expected value: double s00 = data.getSampleDouble(i+0, j+0, band); double s01 = data.getSampleDouble(i+0, j+1, band); double s10 = data.getSampleDouble(i+1, j+0, band); double s11 = data.getSampleDouble(i+1, j+1, band); double s = interpolation.interpolate(s00, s01, s10, s11, 0, 0); assertEquals(s, t, EPS); } } } /** * Tests bilinear intersection at pixel edges. It should be equals * to the average of the four pixels around. */ @Test public void testInterpolationROINoData() { // Following constant is pixel size (in degrees). // This constant must be identical to the one defined in 'getRandomCoverage()' GridCoverage2D coverage = getRandomCoverage(); final Hints hints = new Hints(Hints.TILE_ENCODING, "raw"); final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(hints); Map<String, Object> properties = new HashMap<>(); RenderedImage src = coverage.getRenderedImage(); // Setting ROI and NoData ROIShape roi = new ROIShape(new Rectangle(src.getMinX(), src.getMinY(), src.getWidth()/2, src.getHeight()/2)); CoverageUtilities.setROIProperty(properties, roi); NoDataContainer noDataContainer = new NoDataContainer(15); properties.put("GC_NODATA", noDataContainer); coverage = factory.create("Test2", src, coverage.getEnvelope(), coverage.getSampleDimensions(), null, properties ); final double PIXEL_SIZE = XAffineTransform.getScale((AffineTransform) ((GridGeometry2D)coverage.getGridGeometry()).getGridToCRS()); final Interpolation interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST); coverage = Interpolator2D.create(coverage, new Interpolation[] {interpolation}); final int band = 0; // Band to test. double[] buffer = null; final BorderExtender be = BorderExtender.createInstance(BorderExtender.BORDER_COPY); Rectangle rectangle = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getBounds(); rectangle = new Rectangle(rectangle.x,rectangle.y,rectangle.width+interpolation.getWidth(), rectangle.height+interpolation.getHeight()); final Raster data = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getExtendedData(rectangle,be); final Envelope envelope = coverage.getEnvelope(); final GridEnvelope range = coverage.getGridGeometry().getGridRange(); final double left = envelope.getMinimum(0); final double upper = envelope.getMaximum(1); final Point2D.Double point = new Point2D.Double(); // Will maps to pixel upper-left corner // ROI and NOdata Range nodata = noDataContainer.getAsRange(); double bkg = nodata.getMin(true).doubleValue(); for (int j=range.getSpan(1); j>=0;--j) { for (int i=range.getSpan(0); i>=0;--i) { point.x = left + PIXEL_SIZE * i; point.y = upper - PIXEL_SIZE * j; buffer = coverage.evaluate(point, buffer); double t = buffer[band]; if (!roi.contains(i, j)) { assertEquals(bkg, t, EPS); } else { // Computes the expected value: double s00 = data.getSampleDouble(i, j, band); if (nodata.contains(s00)) { assertEquals(bkg, t, EPS); } else { double s = interpolation.interpolate(new double[][]{{s00}}, 0, 0); assertEquals(s, t, EPS); } } } } } /** * Tests the serialization of a grid coverage. * * @throws IOException if an I/O operation was needed and failed. * @throws ClassNotFoundException Should never happen. */ @Test public void testSerialization() throws IOException, ClassNotFoundException { if (hostnameDefined) { GridCoverage2D coverage = EXAMPLES.get(0); coverage = Interpolator2D.create(coverage, interpolations); GridCoverage2D serial = serialize(coverage); assertNotSame(coverage, serial); assertEquals(Interpolator2D.class, serial.getClass()); // conversions of NaN values which may be the expected ones. assertRasterEquals(coverage, serial); } } }