blob: de7c8b376c991e344505507c8bdde5e54ac8ba00 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sis.map.coverage;
import java.util.List;
import java.awt.image.RenderedImage;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.referencing.operation.transform.LinearTransform;
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.coverage.grid.GridExtent;
import org.apache.sis.coverage.grid.GridGeometry;
import org.apache.sis.coverage.grid.GridCoverage;
import org.apache.sis.storage.AbstractGridCoverageResource;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.util.iso.Names;
// Test dependencies
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.TestCase;
/**
* Test {@link MultiResolutionCoverageLoader}.
*
* @author Martin Desruisseaux (Geomatys)
*/
public final class MultiResolutionCoverageLoaderTest extends TestCase {
/**
* The loader being tested.
*/
private final MultiResolutionCoverageLoader loader;
/**
* Transform from data CRS to the CRS for rendering, or {@code null} if none.
*/
private MathTransform dataToObjective;
/**
* Point where to compute resolution, in coordinates of objective CRS.
* Can be null if {@link #dataToObjective} is null or linear.
*/
private DirectPosition objectivePOI;
/**
* Verifies that a transform with the given scale factors result in the given level to be found.
*/
private void assertLevelEquals(final double sx, final double sy, final double sz, final int expected)
throws TransformException
{
final LinearTransform objectiveToDisplay = MathTransforms.scale(1/sx, 1/sy, 1/sz);
final int level = loader.findPyramidLevel(dataToObjective, objectiveToDisplay, objectivePOI);
assertEquals(expected, level);
}
/**
* Verifies that loading a coverage at the specified level result in a grid coverage
* with the given scale factors.
*/
private void assertLoadEquals(final int level, final double sx, final double sy, final double sz)
throws DataStoreException
{
final GridCoverage coverage = loader.getOrLoad(level);
final MathTransform gridToCRS = coverage.getGridGeometry().getGridToCRS(PixelInCell.CELL_CORNER);
final MathTransform expected = MathTransforms.scale(sx, sy, sz);
assertEquals(expected, gridToCRS);
assertSame(coverage, loader.getOrLoad(level));
}
/**
* Creates a new test case with a loader for a dummy resource.
*
* @throws DataStoreException if an error occurred while querying the dummy resource.
*/
public MultiResolutionCoverageLoaderTest() throws DataStoreException {
loader = new MultiResolutionCoverageLoader(new DummyResource(), null, null);
}
/**
* A dummy resource with arbitrary resolutions for testing purpose.
* Resolutions are ordered from finest (smallest numbers) to coarsest (largest numbers).
*/
private static final class DummyResource extends AbstractGridCoverageResource {
/** Creates a dummy resource. */
DummyResource() {
super(null, false);
}
/** Returns the preferred resolutions in units of CRS axes. */
@Override public List<double[]> getResolutions() {
return List.of(new double[] {2, 3, 1},
new double[] {4, 4, 3},
new double[] {8, 9, 5});
}
/** Returns a grid geometry with the resolution of finest level. */
@Override public GridGeometry getGridGeometry() {
return new GridGeometry(new GridExtent(null, null, new long[] {10, 10, 10}, true),
PixelInCell.CELL_CORNER, MathTransforms.scale(2, 3, 1), null);
}
/** Not needed for this test. */
@Override public List<SampleDimension> getSampleDimensions() {
throw new UnsupportedOperationException();
}
/** Returns a dummy value (will not be used by this test). */
@Override public GridCoverage read(final GridGeometry domain, final int... ranges) {
final SampleDimension band = new SampleDimension(Names.createLocalName(null, null, "dummy"), null, List.of());
return new GridCoverage(domain, List.of(band)) {
@Override public RenderedImage render(GridExtent sliceExtent) {
throw new UnsupportedOperationException(); // Not needed by this test.
}
};
}
}
/**
* Tests {@link MultiResolutionCoverageLoader#findPyramidLevel(MathTransform, LinearTransform, DirectPosition)}
* with no "data to objective" transform.
*
* @throws TransformException if an error occurred while computing the resolution from a transform.
*/
@Test
public void testFindPyramidLevel() throws TransformException {
assertLevelEquals(3, 2, 2, 0);
assertLevelEquals(4, 5, 2, 0);
assertLevelEquals(4, 5, 4, 1);
assertLevelEquals(9, 9, 5, 2);
assertLevelEquals(9, 8, 5, 1);
}
/**
* Tests {@link MultiResolutionCoverageLoader#findPyramidLevel(MathTransform, LinearTransform, DirectPosition)}
* with a "data to objective" transform set to a translation. Because translation has no effect on scale factors,
* the result should be identical to {@link #testFindPyramidLevel()}.
*
* @throws TransformException if an error occurred while computing the resolution from a transform.
*/
@Test
public void testFindWithTranslation() throws TransformException {
dataToObjective = MathTransforms.translation(-5, 7, 3);
testFindPyramidLevel();
}
/**
* Tests {@link MultiResolutionCoverageLoader#getOrLoad(int)}.
*
* @throws DataStoreException if an error occurred while querying the dummy resource.
*/
@Test
public void testGetOrLoad() throws DataStoreException {
assertLoadEquals(2, 8, 9, 5);
assertLoadEquals(0, 2, 3, 1);
assertLoadEquals(1, 4, 4, 3);
}
}