| /* |
| * 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.apache.sis.coverage.grid.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); |
| } |
| } |