/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2007-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2007-2012, 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.sql;
import java.util.TreeSet;
import java.util.SortedSet;
import java.sql.SQLException;
import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import org.opengis.geometry.Envelope;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.referencing.operation.TransformException;
import org.geotoolkit.internal.sql.table.CatalogTestBase;
import org.junit.*;
import static org.junit.Assert.*;
/**
* Tests {@link GridGeometryTable}.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.11
*
* @since 3.10 (derived from Seagis)
*/
public final strictfp class GridGeometryTableTest extends CatalogTestBase {
/**
* The identifier of the geometry to be tested.
* We use the Coriolis (IFREMER) layer.
*/
public static final Integer CORIOLIS_ID = 200;
/**
* The identifier of the BlueMarble geometry.
* Used for testing envelope rounding.
*/
public static final Integer BLUEMARBLE_ID = 333;
/**
* Creates a new test suite.
*/
public GridGeometryTableTest() {
super(GridGeometryTable.class);
}
/**
* Gets the BlueMarble geometry and check its envelope.
*
* @throws SQLException If the test can't connect to the database.
* @throws TransformException Should not happen.
*/
@Test
public void testEnvelope() throws SQLException, TransformException {
final GridGeometryTable table = getDatabase().getTable(GridGeometryTable.class);
final GridGeometryEntry entry = table.getEntry(BLUEMARBLE_ID);
assertEquals("horizontal SRID", 4326, entry.getHorizontalSRID());
final Envelope envelope = entry.geometry.getEnvelope();
/*
* Following assertions require an exact match (tolerance == 0), which should work if
* GeneralGridGeometry constructor invoked GeneralEnvelope.roundIfAlmostInteger(360, 16).
*/
assertEquals(-180, envelope.getMinimum(0), 0);
assertEquals(+180, envelope.getMaximum(0), 0);
assertEquals( -90, envelope.getMinimum(1), 0);
assertEquals( +90, envelope.getMaximum(1), 0);
table.release();
}
/**
* Tests the {@link GridGeometryTable#getEntry}.
*
* @throws SQLException If the test can't connect to the database.
* @throws TransformException Should not happen.
*/
@Test
public void testGetEntry() throws SQLException, TransformException {
final GridGeometryTable table = getDatabase().getTable(GridGeometryTable.class);
final GridGeometryEntry entry = table.getEntry(CORIOLIS_ID);
assertEquals("horizontal SRID", 3395, entry.getHorizontalSRID());
assertEquals("vertical SRID", 5714, entry.getVerticalSRID());
final GridEnvelope gridExtent = entry.geometry.getExtent();
assertEquals("Image width", 720, gridExtent.getSpan(0));
assertEquals("Image height", 499, gridExtent.getSpan(1));
assertEquals("Num. depths", 59, gridExtent.getSpan(2));
final GeographicBoundingBox box = entry.getGeographicBoundingBox();
assertEquals("West bound", -180, box.getWestBoundLongitude(), 1E-10);
assertEquals("East bound", +180, box.getEastBoundLongitude(), 1E-10);
assertEquals("South bouth", -77, box.getSouthBoundLatitude(), 0.5);
assertEquals("North bound", +77, box.getNorthBoundLatitude(), 0.5);
final Envelope envelope = entry.geometry.getEnvelope();
assertEquals("West bound", -2.00E+7, envelope.getMinimum(0), 5E+5);
assertEquals("East bound", +2.00E+7, envelope.getMaximum(0), 5E+5);
assertEquals("South bound", -1.38E+7, envelope.getMinimum(1), 5E+5);
assertEquals("North bound", +1.38E+7, envelope.getMaximum(1), 5E+5);
final Dimension size = entry.getImageSize();
assertEquals("Image width", 720, size.width);
assertEquals("Image height", 499, size.height);
final double[] depths = entry.getVerticalOrdinates();
assertNotNull("Expected an array of depths.", depths);
assertEquals("Test the second depth.", 10, depths[1], 0.0);
assertEquals("Test finding depth index.", 9, entry.indexOfNearestAltitude(100));
final SortedSet<Number> ds = new TreeSet<>();
for (final double depth : depths) {
assertTrue(ds.add(depth));
}
checkCoriolisElevations(ds);
final AffineTransform gridToCRS = entry.gridToCRS;
assertEquals("Scale X", 55659.75, gridToCRS.getScaleX(), 0.01);
assertEquals("Scale Y", -55381.10, gridToCRS.getScaleY(), 0.01);
assertEquals("Translate X", -20037508, gridToCRS.getTranslateX(), 1.0);
assertEquals("Translate Y", 13817585, gridToCRS.getTranslateY(), 1.0);
assertEquals("Shear X", 0, gridToCRS.getShearX(), 0.0);
assertEquals("Shear Y", 0, gridToCRS.getShearY(), 0.0);
assertSame("Expected cached entry.", entry, table.getEntry(CORIOLIS_ID));
table.release();
}
/**
* Tests the {@link GridGeometryTable#find} methods.
*
* @throws SQLException If the test can't connect to the database.
*/
@Test
public void testFind() throws SQLException {
final GridGeometryTable table = getDatabase().getTable(GridGeometryTable.class);
final GridGeometryEntry entry = table.getEntry(CORIOLIS_ID);
final double[] depths = entry.getVerticalOrdinates();
assertEquals("Search the existing entry.", CORIOLIS_ID, table.find(entry.getImageSize(),
entry.gridToCRS, entry.getHorizontalSRID(), depths, entry.getVerticalSRID()));
assertNull("Wrong horizontal SRID.", table.find(entry.getImageSize(),
entry.gridToCRS, 4326, depths, entry.getVerticalSRID()));
depths[1] = 12.8; // Tries a non-existent altitude.
assertNull("Wrong depth.", table.find(entry.getImageSize(),
entry.gridToCRS, entry.getHorizontalSRID(), depths, entry.getVerticalSRID()));
table.release();
}
/**
* Tests the {@link GridGeometryTable#findOrCreate} methods.
*
* @throws SQLException If the test can't connect to the database.
*/
@Test
public void testFindOrCreate() throws SQLException {
final GridGeometryTable table = getDatabase().getTable(GridGeometryTable.class);
final GridGeometryEntry entry = table.getEntry(CORIOLIS_ID);
final double[] depths = entry.getVerticalOrdinates();
depths[1] = 12.8; // Non-existent altitude.
final int id = table.findOrCreate(entry.getImageSize(), entry.gridToCRS,
entry.getHorizontalSRID(), depths, entry.getVerticalSRID());
assertFalse("Should not be the existing ID.", id == CORIOLIS_ID.intValue());
assertEquals("Should find the existing entry.", Integer.valueOf(id),
table.find(entry.getImageSize(), entry.gridToCRS,
entry.getHorizontalSRID(), depths, entry.getVerticalSRID()));
assertEquals("Should have deleted the entry.", 1, table.delete(id));
table.release();
}
/**
* Ensures that the given elevations from the Coriolis layer are equal to the expected values.
*/
static void checkCoriolisElevations(final SortedSet<Number> elevations) {
final Double[] expected = {
5d, 10d, 20d, 30d, 40d, 50d, 60d, 80d, 100d, 120d, 140d, 160d, 180d, 200d, 220d, 240d,
260d, 280d, 300d, 320d, 360d, 400d, 440d, 480d, 520d, 560d, 600d, 640d, 680d, 720d,
760d, 800d, 840d, 880d, 920d, 960d, 1000d, 1040d, 1080d, 1120d, 1160d, 1200d, 1240d,
1280d, 1320d, 1360d, 1400d, 1440d, 1480d, 1520d, 1560d, 1600d, 1650d, 1700d, 1750d,
1800d, 1850d, 1900d, 1950d
};
assertArrayEquals(expected, elevations.toArray(new Double[elevations.size()]));
}
}