/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2014, 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; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Arrays; import org.opengis.coverage.grid.GridEnvelope; import org.opengis.coverage.grid.GridGeometry; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.datum.PixelInCell; import org.opengis.util.FactoryException; import org.apache.sis.internal.referencing.GeodeticObjectBuilder; import org.apache.sis.referencing.CommonCRS; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.coverage.grid.GridCoverageBuilder; import org.geotoolkit.factory.FactoryFinder; import org.geotoolkit.referencing.operation.matrix.GeneralMatrix; import org.geotoolkit.metadata.iso.spatial.PixelTranslation; import org.apache.sis.util.Utilities; import org.junit.Test; import static org.junit.Assert.*; /** * Test GridCoverageStack class. * * @author Johann Sorel (Geomatys) */ public class GridCoverageStackTest extends org.geotoolkit.test.TestBase { private static final double DELTA = 0.00000001; /** * Verify 3D grid coverage stack creation and correct grid geometry. */ @Test public void test3D() throws FactoryException, IOException, TransformException{ final CoordinateReferenceSystem horizontal = CommonCRS.WGS84.normalizedGeographic(); final CoordinateReferenceSystem vertical = CommonCRS.Vertical.ELLIPSOIDAL.crs(); final CoordinateReferenceSystem crs = new GeodeticObjectBuilder().addName("wgs84+ele") .createCompoundCRS(horizontal, vertical); final GridCoverageStack stack = createCube3D(100, 100, crs); assertTrue(Utilities.equalsIgnoreMetadata(crs, stack.getCoordinateReferenceSystem())); final GridGeometry gridGeom = stack.getGridGeometry(); assertNotNull(gridGeom); //check grid envelope final GridEnvelope gridEnv = gridGeom.getExtent(); assertNotNull(gridEnv); assertEquals(3,gridEnv.getDimension()); assertEquals(0, gridEnv.getLow(0)); assertEquals(0, gridEnv.getLow(1)); assertEquals(0, gridEnv.getLow(2)); assertEquals(99, gridEnv.getHigh(0)); assertEquals(99, gridEnv.getHigh(1)); assertEquals(2, gridEnv.getHigh(2)); //check grid to crs final MathTransform gridToCRS = PixelTranslation.translate(gridGeom.getGridToCRS(), PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER); assertEquals(3, gridToCRS.getSourceDimensions()); assertEquals(3, gridToCRS.getTargetDimensions()); final double[] lower = new double[]{0,0,0}; final double[] upper = new double[]{99,99,2}; gridToCRS.transform(lower,0,lower,0,1); gridToCRS.transform(upper,0,upper,0,1); assertEquals(0.0, lower[0], DELTA); assertEquals(0.0, lower[1], DELTA); assertEquals(10, lower[2], DELTA); assertEquals(99, upper[0], DELTA); assertEquals(99, upper[1], DELTA); assertEquals(50, upper[2], DELTA); } /** * Verify 4D grid coverage stack creation and correct grid geometry. */ @Test public void test4D() throws FactoryException, IOException, TransformException{ final CoordinateReferenceSystem horizontal = CommonCRS.WGS84.normalizedGeographic(); final CoordinateReferenceSystem vertical = CommonCRS.Vertical.ELLIPSOIDAL.crs(); final CoordinateReferenceSystem temporal = CommonCRS.Temporal.JAVA.crs(); final CoordinateReferenceSystem crs3d = new GeodeticObjectBuilder().addName("wgs84+ele") .createCompoundCRS(horizontal,vertical); final CoordinateReferenceSystem crs4d = new GeodeticObjectBuilder().addName("wgs84+ele+time") .createCompoundCRS(crs3d,temporal); final GridCoverageStack stack = createCube4D(100, 100, crs4d); assertTrue(Utilities.equalsIgnoreMetadata(crs4d, stack.getCoordinateReferenceSystem())); final GridGeometry gridGeom = stack.getGridGeometry(); assertNotNull(gridGeom); //check grid envelope final GridEnvelope gridEnv = gridGeom.getExtent(); assertNotNull(gridEnv); assertEquals(4,gridEnv.getDimension()); assertEquals(0, gridEnv.getLow(0)); assertEquals(0, gridEnv.getLow(1)); assertEquals(0, gridEnv.getLow(2)); assertEquals(0, gridEnv.getLow(3)); assertEquals(99, gridEnv.getHigh(0)); assertEquals(99, gridEnv.getHigh(1)); assertEquals(2, gridEnv.getHigh(2)); assertEquals(3, gridEnv.getHigh(3)); //check grid to crs //-- in convention gridToCrs in PixelInCell.Center final MathTransform gridToCRS = PixelTranslation.translate(gridGeom.getGridToCRS(), PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER); assertEquals(4, gridToCRS.getSourceDimensions()); assertEquals(4, gridToCRS.getTargetDimensions()); final double[] lower = new double[]{0,0,0,0}; final double[] upper = new double[]{99,99,2,3}; gridToCRS.transform(lower,0,lower,0,1); gridToCRS.transform(upper,0,upper,0,1); assertEquals(0.0, lower[0], DELTA); assertEquals(0.0, lower[1], DELTA); assertEquals(10, lower[2], DELTA); assertEquals(3, lower[3], DELTA); assertEquals( 99, upper[0], DELTA); assertEquals( 99, upper[1], DELTA); assertEquals( 50, upper[2], DELTA); assertEquals( 12, upper[3], DELTA); } private static GridCoverageStack createCube4D(int width, int height, CoordinateReferenceSystem crs) throws IOException, TransformException, FactoryException{ final GridCoverageStack slice0 = createSubStack3D(width, height, 3, crs); final GridCoverageStack slice1 = createSubStack3D(width, height, 6, crs); final GridCoverageStack slice2 = createSubStack3D(width, height, 9, crs); final GridCoverageStack slice3 = createSubStack3D(width, height, 12, crs); return new GridCoverageStack("4d", Arrays.asList(slice0,slice1,slice2,slice3), 3); } private static GridCoverageStack createSubStack3D(int width, int height, double t, CoordinateReferenceSystem crs) throws IOException, TransformException, FactoryException{ final GridCoverage2D slice0 = createSlice4D(width, height, 10, t, crs); final GridCoverage2D slice1 = createSlice4D(width, height, 20, t, crs); final GridCoverage2D slice2 = createSlice4D(width, height, 50, t, crs); return new GridCoverageStack(null, Arrays.asList(slice0,slice1,slice2), 2); } private static GridCoverageStack createCube3D(int width, int height, CoordinateReferenceSystem crs) throws IOException, TransformException, FactoryException{ final GridCoverage2D slice0 = createSlice3D(width, height, 10, crs); final GridCoverage2D slice1 = createSlice3D(width, height, 20, crs); final GridCoverage2D slice2 = createSlice3D(width, height, 50, crs); return new GridCoverageStack(null, Arrays.asList(slice0,slice1,slice2), 2); } private static GridCoverage2D createSlice3D(int width, int height, double z, CoordinateReferenceSystem crs) throws FactoryException{ final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final GeneralMatrix matrix = new GeneralMatrix(4); matrix.setIdentity(); matrix.setElement(2, 3, z); final MathTransformFactory mf = FactoryFinder.getMathTransformFactory(null); final MathTransform gridtoCrs = mf.createAffineTransform(matrix); final GridCoverageBuilder gcb = new GridCoverageBuilder(); gcb.setName("slice"); gcb.setPixelAnchor(PixelInCell.CELL_CORNER); gcb.setCoordinateReferenceSystem(crs); gcb.setGridToCRS(gridtoCrs); gcb.setRenderedImage(image); return gcb.getGridCoverage2D(); } private static GridCoverage2D createSlice4D(int width, int height, double z, double t, CoordinateReferenceSystem crs) throws FactoryException{ final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final GeneralMatrix matrix = new GeneralMatrix(5); matrix.setIdentity(); matrix.setElement(2, 4, z); matrix.setElement(3, 4, t); final MathTransformFactory mf = FactoryFinder.getMathTransformFactory(null); final MathTransform gridtoCrs = mf.createAffineTransform(matrix); final GridCoverageBuilder gcb = new GridCoverageBuilder(); gcb.setName("slice"); gcb.setPixelAnchor(PixelInCell.CELL_CORNER); gcb.setCoordinateReferenceSystem(crs); gcb.setGridToCRS(gridtoCrs); gcb.setRenderedImage(image); return gcb.getGridCoverage2D(); } }