sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jso...@apache.org
Subject [sis] 02/02: Add coverage query expansion test cases, add readonly memory grid resource
Date Tue, 01 Sep 2020 12:03:28 GMT
This is an automated email from the ASF dual-hosted git repository.

jsorel pushed a commit to branch feat/sourceDomainExpansion
in repository https://gitbox.apache.org/repos/asf/sis.git

commit fbd5f3134ae9647dba14e9b9cea6de91cfdfcc7a
Author: jsorel <johann.sorel@geomatys.com>
AuthorDate: Tue Sep 1 14:02:57 2020 +0200

    Add coverage query expansion test cases, add readonly memory grid resource
---
 .../sis/internal/storage/MemoryGridResource.java   | 143 +++++++++++++++++++++
 .../internal/storage/query/CoverageQueryTest.java  | 120 +++++++++++++++++
 .../apache/sis/test/suite/StorageTestSuite.java    |   1 +
 3 files changed, 264 insertions(+)

diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryGridResource.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryGridResource.java
new file mode 100644
index 0000000..b451ca5
--- /dev/null
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryGridResource.java
@@ -0,0 +1,143 @@
+/*
+ * 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.internal.storage;
+
+import java.awt.image.RenderedImage;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.sis.coverage.SampleDimension;
+import org.apache.sis.coverage.grid.GridCoverage;
+import org.apache.sis.coverage.grid.GridCoverage2D;
+import org.apache.sis.coverage.grid.GridCoverageBuilder;
+import org.apache.sis.coverage.grid.GridDerivation;
+import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.grid.GridGeometry;
+import org.apache.sis.coverage.grid.GridRoundingMode;
+import org.apache.sis.image.ImageProcessor;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.event.StoreListeners;
+import org.apache.sis.util.ArgumentChecks;
+import org.opengis.referencing.datum.PixelInCell;
+
+/**
+ * A GridCoverage resource in memory. The GridCoverage is specified at construction time.
+ * Metadata can be specified by overriding {@link #createMetadata(MetadataBuilder)}.
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @version 1.1
+ * @since   1.1
+ * @module
+ */
+public class MemoryGridResource extends AbstractGridResource {
+
+    private final GridCoverage2D coverage;
+
+    /**
+     * Creates a new coverage stored in memory.
+     *
+     * @param parent     listeners of the parent resource, or {@code null} if none.
+     * @param coverage   stored coverage, coverage will not be copied, can not be null.
+     */
+    public MemoryGridResource(final StoreListeners parent, final GridCoverage2D coverage)
{
+        super(parent);
+        ArgumentChecks.ensureNonNull("coverage", coverage);
+        this.coverage = coverage;
+    }
+
+    /**
+     * {@inheritDoc }
+     *
+     * @return extent of grid coordinates together with their mapping to "real world" coordinates.
+     * @throws DataStoreException if an error occurred while reading definitions from the
underlying data store.
+     */
+    @Override
+    public GridGeometry getGridGeometry() throws DataStoreException {
+        return coverage.getGridGeometry();
+    }
+
+    /**
+     * {@inheritDoc }
+     *
+     * @return ranges of sample values together with their mapping to "real values".
+     * @throws DataStoreException if an error occurred while reading definitions from the
underlying data store.
+     */
+    @Override
+    public List<SampleDimension> getSampleDimensions() throws DataStoreException {
+        return coverage.getSampleDimensions();
+    }
+
+    /**
+     * {@inheritDoc }
+     *
+     * @param  domain  desired grid extent and resolution, or {@code null} for reading the
whole domain.
+     * @param  range   0-based indices of sample dimensions to read, or {@code null} or an
empty sequence for reading them all.
+     * @return the grid coverage for the specified domain and range.
+     * @throws DataStoreException if an error occurred while reading the grid coverage data.
+     */
+    @Override
+    public GridCoverage read(GridGeometry domain, int... range) throws DataStoreException
{
+
+        //quick return of the original coverage
+        if (domain == null && (range == null || range.length == 0)) {
+            return coverage;
+        }
+
+        /*
+        Subsampling is ignored because it is an expensive operation.
+        Clipping and range selection are light and current implementation
+        do not copy any data.
+        */
+        GridGeometry areaOfInterest = coverage.getGridGeometry();
+        GridExtent intersection = areaOfInterest.getExtent();
+        if (domain != null) {
+            final GridDerivation derivation = getGridGeometry().derive()
+                    .rounding(GridRoundingMode.ENCLOSING)
+                    .subgrid(domain);
+            intersection = derivation.getIntersection();
+            /*
+            Extent is left as null, the grid coverage builder will extract the size from
the image.
+            Image size and offset may not be exactly what was requested by the intersection.
+            */
+            areaOfInterest = new GridGeometry(null,
+                    PixelInCell.CELL_CENTER,
+                    areaOfInterest.getGridToCRS(PixelInCell.CELL_CENTER),
+                    areaOfInterest.getCoordinateReferenceSystem());
+        }
+
+        RenderedImage render = coverage.render(intersection);
+
+        /*
+        Select range.
+        */
+        List<SampleDimension> sampleDimensions = coverage.getSampleDimensions();
+        if (range != null && range.length > 0) {
+            render = new ImageProcessor().selectBands(render, range);
+            final List<SampleDimension> sds = new ArrayList<>();
+            for (int i : range) {
+                sds.add(sampleDimensions.get(i));
+            }
+            sampleDimensions = sds;
+        }
+
+        final GridCoverageBuilder gcb = new GridCoverageBuilder();
+        gcb.setValues(render);
+        gcb.setRanges(sampleDimensions);
+        gcb.setDomain(areaOfInterest);
+        return gcb.build();
+    }
+
+}
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/CoverageQueryTest.java
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/CoverageQueryTest.java
new file mode 100644
index 0000000..2c8e3fd
--- /dev/null
+++ b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/query/CoverageQueryTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.internal.storage.query;
+
+import java.awt.image.BufferedImage;
+import org.apache.sis.coverage.grid.GridCoverage;
+import org.apache.sis.coverage.grid.GridCoverage2D;
+import org.apache.sis.coverage.grid.GridCoverageBuilder;
+import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.grid.GridGeometry;
+import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
+import org.apache.sis.internal.storage.MemoryGridResource;
+import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.test.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opengis.metadata.spatial.DimensionNameType;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.PixelInCell;
+
+/**
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @version 1.1
+ * @since   1.1
+ */
+public final strictfp class CoverageQueryTest extends TestCase {
+
+    /**
+     * Verify source domain expansion parameter is used.
+     */
+    @Test
+    public void sourceExpansionTest() throws DataStoreException {
+
+        final CoordinateReferenceSystem crs = CommonCRS.WGS84.normalizedGeographic();
+        final AffineTransform2D gridToCrs = new AffineTransform2D(1, 0, 0, 1, 0, 0);
+        final GridCoverageResource resource;
+        { //create resource
+            final GridGeometry grid = new GridGeometry(new GridExtent(100, 100), PixelInCell.CELL_CENTER,
gridToCrs, crs);
+            final BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+
+            final GridCoverageBuilder gcb = new GridCoverageBuilder();
+            gcb.setDomain(grid);
+            gcb.setValues(image);
+            final GridCoverage coverage = gcb.build();
+            resource = new MemoryGridResource(null, (GridCoverage2D) coverage);
+        }
+
+        { // test without any parameter
+            final CoverageQuery query = new CoverageQuery();
+            final GridCoverageResource subres = resource.subset(query);
+            Assert.assertEquals(resource.getGridGeometry(), subres.getGridGeometry());
+        }
+
+        { // test with sub grid geometry
+            final GridGeometry subGrid = new GridGeometry(new GridExtent(
+                    new DimensionNameType[]{DimensionNameType.COLUMN, DimensionNameType.ROW},
+                    new long[]{20, 20}, new long[]{40, 40}, true),
+                    PixelInCell.CELL_CENTER, gridToCrs, crs);
+
+            final CoverageQuery query = new CoverageQuery();
+            query.setDomain(subGrid);
+
+            final GridCoverageResource subres = resource.subset(query);
+            Assert.assertEquals(subGrid, subres.getGridGeometry());
+        }
+
+        { // test with sub grid geometry + expansion
+            final GridGeometry subGrid = new GridGeometry(new GridExtent(
+                    new DimensionNameType[]{DimensionNameType.COLUMN, DimensionNameType.ROW},
+                    new long[]{20, 20}, new long[]{40, 40}, true),
+                    PixelInCell.CELL_CENTER, gridToCrs, crs);
+
+            final CoverageQuery query = new CoverageQuery();
+            query.setDomain(subGrid);
+            query.setSourceDomainExpansion(3);
+
+            final GridCoverageResource subres = resource.subset(query);
+
+            final GridGeometry expGrid = new GridGeometry(new GridExtent(
+                    new DimensionNameType[]{DimensionNameType.COLUMN, DimensionNameType.ROW},
+                    new long[]{17, 17}, new long[]{43, 43}, true),
+                    PixelInCell.CELL_CENTER, gridToCrs, crs);
+
+            Assert.assertEquals(expGrid, subres.getGridGeometry());
+
+
+            //read operation must add the expected margins
+            //this last test is only to avoid regression
+            //GridCoverage2D implementation returns a larger area then requested
+            final GridGeometry readGrid = new GridGeometry(new GridExtent(
+                    new DimensionNameType[]{DimensionNameType.COLUMN, DimensionNameType.ROW},
+                    new long[]{30, 30}, new long[]{35, 35}, true),
+                    PixelInCell.CELL_CENTER, gridToCrs, crs);
+            GridCoverage coverage = subres.read(readGrid);
+
+            final GridGeometry expReadGrid = resource.getGridGeometry();
+
+            Assert.assertEquals(expReadGrid, coverage.getGridGeometry());
+
+        }
+    }
+
+}
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
b/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
index bbabdf6..600a9ad 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
@@ -44,6 +44,7 @@ import org.junit.BeforeClass;
     org.apache.sis.storage.ProbeResultTest.class,
     org.apache.sis.storage.StorageConnectorTest.class,
     org.apache.sis.storage.event.StoreListenersTest.class,
+    org.apache.sis.internal.storage.query.CoverageQueryTest.class,
     org.apache.sis.internal.storage.query.SimpleQueryTest.class,
     org.apache.sis.internal.storage.xml.MimeTypeDetectorTest.class,
     org.apache.sis.internal.storage.xml.StoreProviderTest.class,


Mime
View raw message