/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2015, 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.combineIterator; import java.util.ArrayList; import java.util.List; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.crs.CompoundCRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.util.FactoryException; import org.opengis.geometry.Envelope; import org.apache.sis.internal.referencing.GeodeticObjectBuilder; import org.apache.sis.internal.referencing.j2d.AffineTransform2D; import org.apache.sis.measure.NumberRange; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.operation.matrix.Matrices; import org.apache.sis.referencing.operation.matrix.MatrixSIS; import org.apache.sis.referencing.operation.transform.MathTransforms; import org.geotoolkit.coverage.grid.GeneralGridEnvelope; import org.geotoolkit.referencing.crs.PredefinedCRS; import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.*; /** * Test multidimensionnal {@link Envelope} iterator, {@link GridCombineIterator}. * * @author Remi Marechal(Geomatys). * @version 4.0 * @since 4.0 */ public strictfp class GridCombineIteratorTest extends org.geotoolkit.test.TestBase { /** * Current tolerance. */ private static final double TOLERANCE = 1E-12; /** * Test iterator in particularity 2 dimensional case. */ @Test public void test2D() { final CoordinateReferenceSystem crsTest = PredefinedCRS.CARTESIAN_2D; final int[] gridLow = new int[]{0,0}; final int[] gridHigh = new int[]{1,1}; GeneralGridEnvelope extent = new GeneralGridEnvelope(gridLow, gridHigh, true); GridCombineIterator it = new GridCombineIterator(extent, crsTest, new AffineTransform2D(1, 0, 0, 1, 0, 0)); final List<Envelope> listEnvelope = new ArrayList<Envelope>(); while (it.hasNext()) { listEnvelope.add(it.next()); } assertTrue(listEnvelope.size() == 1); Envelope result = listEnvelope.get(0); checkEnvelope(result, gridLow[0], gridLow[1], gridHigh[0], gridHigh[1]); //-- test with exclusive high border //-- should return only low point extent = new GeneralGridEnvelope(gridLow, gridHigh, false); it = new GridCombineIterator(extent, crsTest, new AffineTransform2D(1, 0, 0, 1, 0, 0)); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } assertTrue(listEnvelope.size() == 1); result = listEnvelope.get(0); assertSame(result.getCoordinateReferenceSystem(), crsTest); checkEnvelope(result, gridLow[0], gridLow[1], gridLow[0], gridLow[1]); gridLow[0] = -5; gridLow[1] = -7; gridHigh[0] = 13; gridHigh[1] = 11; extent = new GeneralGridEnvelope(gridLow, gridHigh, true); it = new GridCombineIterator(extent, crsTest, new AffineTransform2D(2,0,0,3,-3,5)); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } assertTrue(listEnvelope.size() == 1); result = listEnvelope.get(0); assertSame(result.getCoordinateReferenceSystem(), crsTest); checkEnvelope(result, -13, -16, 23, 38); //-- test with exclusive high border extent = new GeneralGridEnvelope(gridLow, gridHigh, false); it = new GridCombineIterator(extent, crsTest, new AffineTransform2D(2,0,0,3,-3,5)); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } assertTrue(listEnvelope.size() == 1); result = listEnvelope.get(0); assertSame(result.getCoordinateReferenceSystem(), crsTest); checkEnvelope(result, -13, -16, 21, 35); } /** * Test iterator in particularity 2 dimensional case. */ @Test public void test3D() throws FactoryException { final int[] gridLow = new int[]{0, 0, 0}; final int[] gridHigh = new int[]{1, 1, 1}; GeneralGridEnvelope extent = new GeneralGridEnvelope(gridLow, gridHigh, true); final CoordinateReferenceSystem crs3D = new GeodeticObjectBuilder().addName("compoundcrstest") .createCompoundCRS(PredefinedCRS.CARTESIAN_2D, CommonCRS.Temporal.JAVA.crs()); final MatrixSIS mat = Matrices.createDiagonal(4, 4);//-- identity GridCombineIterator it = new GridCombineIterator(extent, crs3D, MathTransforms.linear(mat)); final List<Envelope> listEnvelope = new ArrayList<Envelope>(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- one slice in 0 temporal //-- second slice in 1 temporal assertTrue(listEnvelope.size() == 2); Envelope result = listEnvelope.get(0); assertSame(result.getCoordinateReferenceSystem(), crs3D); //-- slice in temporal value 0 (gridLow[2]) checkEnvelope(result, gridLow[0], gridLow[1], gridLow[2], gridHigh[0], gridHigh[1], gridLow[2]); result = listEnvelope.get(1); assertSame(result.getCoordinateReferenceSystem(), crs3D); //-- slice in temporal value 1 (gridHigh[2]) checkEnvelope(result, gridLow[0], gridLow[1], gridHigh[2], gridHigh[0], gridHigh[1], gridHigh[2]); //-- test with exclusive high border //-- should return only low point extent = new GeneralGridEnvelope(gridLow, gridHigh, false); it = new GridCombineIterator(extent, crs3D, MathTransforms.linear(mat)); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- expected one point assertTrue(listEnvelope.size() == 1); //-- only one point at temporal dim 0 result = listEnvelope.get(0); assertSame(result.getCoordinateReferenceSystem(), crs3D); checkEnvelope(result, gridLow[0], gridLow[1], gridLow[2], gridLow[0], gridLow[1], gridLow[2]); //-- temporal multi slice gridLow[2] = -2; gridHigh[2] = 1; extent = new GeneralGridEnvelope(gridLow, gridHigh, true); it = new GridCombineIterator(extent, crs3D, MathTransforms.linear(mat)); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- expected one point assertTrue("expected 4 results. found : "+listEnvelope.size(), listEnvelope.size() == 4);//-- for t = {-2, -1, 0, 1} final int firstTemp = -2; for (int i = 0; i < 4; i++) { //-- check value for each respectively temporal value final Envelope env = listEnvelope.get(i); checkEnvelope(env, gridLow[0], gridLow[1], firstTemp + i, gridHigh[0], gridHigh[1], firstTemp + i); } } /** * Test with 4 D crs and also, the horizontal part of the {@link CompoundCRS} is between two another crs like follow. * MyCompoundCrs = [Temporal][2D part][elevation]; */ @Test public void testmultidim() throws FactoryException { final CoordinateReferenceSystem ccrs = new GeodeticObjectBuilder().addName("compoundcrstest") .createCompoundCRS(CommonCRS.Temporal.JAVA.crs(), CommonCRS.WGS84.geographic(), CommonCRS.Vertical.DEPTH.crs()); final int[] gridLow = new int[]{-2, 0, 0, 1}; final int[] gridHigh = new int[]{ 0, 11, 11, 4}; //-- 11 because exclusive high border GeneralGridEnvelope extent = new GeneralGridEnvelope(gridLow, gridHigh, false);//-- exclusive high border MatrixSIS mat = Matrices.createDiagonal(5, 5);//-- identity mat.setElements(new double[]{2, 0, 0, 0, -3, //-- Temporal ordinate 0, 36, 0, 0, -180, //-- 2D crs part (WGS84) long 0, 0, 18, 0, -90, //-- 2D part lat 0, 0, 0, 3, 5, //-- elevation ordinate 0, 0, 0, 0, 1 }); GridCombineIterator it = new GridCombineIterator(extent, ccrs, MathTransforms.linear(mat)); final List<Envelope> listEnvelope = new ArrayList<Envelope>(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- for t = {-2, -1} "*" h = {1, 2, 3} assertTrue("expected 6 results. found : "+listEnvelope.size(), listEnvelope.size() == 6); assertSame(listEnvelope.get(0).getCoordinateReferenceSystem(), ccrs); //-- expected t = -2, h = 1 checkEnvelope(listEnvelope.get(0), -7, -180, -90, 8, -7, 180, 90, 8); //-- expected t = -2, h = 2 checkEnvelope(listEnvelope.get(1), -7, -180, -90, 11, -7, 180, 90, 11); //-- expected t = -2, h = 3 checkEnvelope(listEnvelope.get(2), -7, -180, -90, 14, -7, 180, 90, 14); //-- expected t = -1, h = 1 checkEnvelope(listEnvelope.get(3), -5, -180, -90, 8, -5, 180, 90, 8); //-- expected t = -2, h = 2 checkEnvelope(listEnvelope.get(4), -5, -180, -90, 11, -5, 180, 90, 11); //-- expected t = -2, h = 3 checkEnvelope(listEnvelope.get(5), -5, -180, -90, 14, -5, 180, 90, 14); //---------------------------------------------------// //-- test iteration on only one expected dimension --// //---------------------------------------------------// //-- first on ordinate 0 it = new GridCombineIterator(extent, null, MathTransforms.linear(mat), 0); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- for t = {-2, -1} assertTrue("expected 2 results when iteration on 0 ordinate. found : "+listEnvelope.size(), listEnvelope.size() == 2); assertTrue("expected null crs", listEnvelope.get(0).getCoordinateReferenceSystem() == null); //-- expected t = -2, h = {1; 4} checkEnvelope(listEnvelope.get(0), -7, -180, -90, 8, -7, 180, 90, 14); //-- expected t = -2, h = {1; 4} checkEnvelope(listEnvelope.get(1), -5, -180, -90, 8, -5, 180, 90, 14); //-- first on ordinate 3 it = new GridCombineIterator(extent, null, MathTransforms.linear(mat), 3); listEnvelope.clear(); while (it.hasNext()) { listEnvelope.add(it.next()); } //-- for h = {1, 2, 3} assertTrue("expected 3 results when iteration on 3 ordinate. found : "+listEnvelope.size(), listEnvelope.size() == 3); assertTrue("expected null crs", listEnvelope.get(0).getCoordinateReferenceSystem() == null); //-- expected t = {-2; -1}, h = 1 checkEnvelope(listEnvelope.get(0), -7, -180, -90, 8, -5, 180, 90, 8); //-- expected t = {-2; -1}, h = 2 checkEnvelope(listEnvelope.get(1), -7, -180, -90, 11, -5, 180, 90, 11); //-- expected t = {-2; -1}, h = 3 checkEnvelope(listEnvelope.get(2), -7, -180, -90, 14, -5, 180, 90, 14); //-- test extract axis values NumberRange<Double>[] scales = GridCombineIterator.extractAxisRanges(extent, MathTransforms.linear(mat), 0); assertEquals("extract axis values at dimension 0", scales[0].getMinDouble(), -7, TOLERANCE); assertEquals("extract axis values at dimension 0", scales[0].getMaxDouble(), -7, TOLERANCE); assertEquals("extract axis values at dimension 1", scales[1].getMinDouble(), -5, TOLERANCE); assertEquals("extract axis values at dimension 1", scales[1].getMaxDouble(), -5, TOLERANCE); // assertArrayEquals("extract axis values at dimension 0", scales, new double[]{-7, -5}, TOLERANCE); scales = GridCombineIterator.extractAxisRanges(extent, MathTransforms.linear(mat), 3); assertEquals("extract axis values at dimension 0", scales[0].getMinDouble(), 8, TOLERANCE); assertEquals("extract axis values at dimension 0", scales[0].getMaxDouble(), 8, TOLERANCE); assertEquals("extract axis values at dimension 1", scales[1].getMinDouble(), 11, TOLERANCE); assertEquals("extract axis values at dimension 1", scales[1].getMaxDouble(), 11, TOLERANCE); assertEquals("extract axis values at dimension 2", scales[2].getMinDouble(), 14, TOLERANCE); assertEquals("extract axis values at dimension 2", scales[2].getMaxDouble(), 14, TOLERANCE); // assertArrayEquals("extract axis values at dimension 3", scales, new double[]{8, 11, 14}, TOLERANCE); //-- test fail try { it = new GridCombineIterator(extent, ccrs, MathTransforms.linear(mat), 1); Assert.fail("test should had failed"); } catch (MismatchedDimensionException ex) { //-- expected comportement } } /** * Check expected {@link Envelope} corners values. * * @param envelope current tested envelope. * @param expectedCorners dim0min, dim1min ... dimNmin, dim0max, dim1max ... dimNmax */ private void checkEnvelope(final Envelope envelope, final double ...expectedCorners) { assert expectedCorners.length % 2 == 0 : "GridCombineIterator : expectedCorners.length must be modulo 2."; assert envelope.getDimension() == expectedCorners.length / 2 : "GridCombineIterator : expectedCorners.length / 2 must be equal to envelope dimension."; final int dim = envelope.getDimension(); for (int d = 0; d < dim; d++) { assertEquals("at envelope.getMinimum("+d+")", expectedCorners[d], envelope.getMinimum(d), TOLERANCE); assertEquals("at envelope.getMaximum("+d+")", expectedCorners[dim + d], envelope.getMaximum(d), TOLERANCE); } } }