This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 544f7f9d2bc6ff33437fa9f456cfed9554fa8a73 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sat Nov 11 16:34:31 2023 +0100 Add a `DataStores.readGridCoverage(…)` convenience method. --- .../org/apache/sis/metadata/MetadataStandard.java | 2 +- .../sis/referencing/internal/MergedProperties.java | 4 +- .../main/org/apache/sis/storage/DataStores.java | 60 +++++++++++++++++++++- .../apache/sis/storage/RasterLoadingStrategy.java | 5 +- .../apache/sis/storage/image/SingleImageStore.java | 5 +- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/MetadataStandard.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/MetadataStandard.java index 7b12df0ddd..43952c8d15 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/MetadataStandard.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/MetadataStandard.java @@ -482,7 +482,7 @@ public class MetadataStandard implements Serializable { * <p>This method ignores dependencies. Fallback on metadata standard dependencies shall be done by the caller.</p> * * @param key the standard interface or the implementation class. - * @return the single interface, or {@code null} if none where found. + * @return the single interface, or {@code null} if none was found. */ private Class<?> findInterface(final CacheKey key) { assert key.isValid() : key; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/MergedProperties.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/MergedProperties.java index 3999303215..e977db4030 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/MergedProperties.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/MergedProperties.java @@ -22,8 +22,8 @@ import org.apache.sis.util.internal.AbstractMap; /** - * A map which first looks for values in a user supplied map, then looks in a default map if no value where found - * in the user supplied one. This map is for {@link org.apache.sis.referencing.factory.GeodeticObjectFactory} and + * A map which first looks for values in a user supplied map, then looks in a default map if no value was found + * in the user supplied map. This map is for {@link org.apache.sis.referencing.factory.GeodeticObjectFactory} and * other SIS factories internal usage only. * * @author Martin Desruisseaux (Geomatys) diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java index 7a6c56edd1..c4ce0b2eb9 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java @@ -16,11 +16,17 @@ */ package org.apache.sis.storage; +import java.util.Optional; import java.util.Collection; import java.util.function.Predicate; +import org.opengis.geometry.Envelope; import org.apache.sis.util.Static; +import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.storage.base.Capability; import org.apache.sis.storage.image.DataStoreFilter; +import org.apache.sis.coverage.grid.GridCoverage; +import org.apache.sis.coverage.grid.GridGeometry; +import org.apache.sis.coverage.grid.DisjointExtentException; /** @@ -30,7 +36,7 @@ import org.apache.sis.storage.image.DataStoreFilter; * * @author Martin Desruisseaux (Geomatys) * @author Johann Sorel (Geomatys) - * @version 1.4 + * @version 1.5 * @since 0.4 */ public final class DataStores extends Static { @@ -122,4 +128,56 @@ public final class DataStores extends Static { } return DataStoreRegistry.INSTANCE.open(storage, Capability.WRITE, preferred); } + + /** + * Reads immediately the first grid coverage found in the given storage. + * This is a convenience method searching for the first instance of {@link GridCoverageResource}. + * If the given storage contains two or more such instances, all resources after the first one are ignored. + * + * <p>The Area Of Interest (AOI) is an optional argument for reducing the amount of data to load. + * It can be expressed using an arbitrary Coordinate Reference System (CRS), as transformations will be applied as needed. + * If the AOI does not specify a CRS, then the AOI is assumed to be in the CRS of the grid coverage to read. + * The returned grid coverage will not necessarily cover exactly the specified AOI. + * It may be smaller if the coverage does not cover the full AOI, + * or it may be larger for loading an integer number of tiles.</p> + * + * <p>On return, the grid coverage (possibly intersected with the AOI) has been fully loaded in memory. + * If lower memory consumption is desired, for example because the coverage is very large, then deferred + * tile loading should be used. The latter approach requires that the caller use {@link DataStore} directly, + * because the store needs to be open as long as the {@link GridCoverage} is used. + * See {@link RasterLoadingStrategy} for more details.</p> + * + * @param storage the input object as a URL, file, image input stream, <i>etc.</i>. + * @param aoi spatiotemporal region of interest, or {@code null} for reading the whole coverage. + * @return the first grid coverage found in the given storage, or an empty value if none was found. + * @throws UnsupportedStorageException if no {@link DataStoreProvider} is found for the given storage object. + * @throws DataStoreException if an error occurred while opening the storage or reading the grid coverage. + * @throws DisjointExtentException if the given envelope does not intersect any resource extent. + * + * @since 1.5 + */ + public static Optional<GridCoverage> readGridCoverage(final Object storage, final Envelope aoi) + throws UnsupportedStorageException, DataStoreException + { + final GridGeometry domain = (aoi == null) ? null : new GridGeometry(aoi); + try (DataStore ds = open(storage)) { + final GridCoverageResource gc; +search: if (ds instanceof GridCoverageResource) { + gc = (GridCoverageResource) ds; + } else { + if (ds instanceof Aggregate) { + for (final Resource r : ((Aggregate) ds).components()) { + if (r instanceof GridCoverageResource) { + gc = (GridCoverageResource) r; + break search; + } + } + } + return Optional.empty(); + } + return Optional.of(gc.read(domain, null)); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(DataStoreException.class); + } + } } diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/RasterLoadingStrategy.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/RasterLoadingStrategy.java index 7d9a036f4c..7fc001905f 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/RasterLoadingStrategy.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/RasterLoadingStrategy.java @@ -42,7 +42,10 @@ import org.opengis.coverage.CannotEvaluateException; * * @author Martin Desruisseaux (Geomatys) * @version 1.1 - * @since 1.1 + * + * @see GridCoverageResource#setLoadingStrategy(RasterLoadingStrategy) + * + * @since 1.1 */ public enum RasterLoadingStrategy { /** diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/SingleImageStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/SingleImageStore.java index 718690c44f..cd8f1ddf69 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/SingleImageStore.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/SingleImageStore.java @@ -28,6 +28,7 @@ import org.apache.sis.storage.GridCoverageResource; import org.apache.sis.storage.RasterLoadingStrategy; import org.apache.sis.storage.UnsupportedQueryException; import org.apache.sis.storage.Query; +import org.apache.sis.util.collection.BackingStoreException; /** @@ -75,8 +76,10 @@ final class SingleImageStore extends WorldFileStore implements GridCoverageResou */ final WorldFileResource delegate() throws DataStoreException { WorldFileResource r = delegate; - if (r == null) { + if (r == null) try { delegate = r = ((Components) components()).get(MAIN_IMAGE); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(DataStoreException.class); } return r; }