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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new c69c10ddfc Provide a `MergeStrategy` option and provide more 
information in the error message if 
`ConcConcatenatedGridCoverage.render(GridExtent)` can not infer a slice.
c69c10ddfc is described below

commit c69c10ddfc32d25a54ce330edf0070f716cbdf67
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Sep 14 19:10:50 2022 +0200

    Provide a `MergeStrategy` option and provide more information in the error 
message if `ConcConcatenatedGridCoverage.render(GridExtent)` can not infer a 
slice.
---
 .../org/apache/sis/internal/storage/Resources.java | 10 ++++
 .../sis/internal/storage/Resources.properties      |  2 +
 .../sis/internal/storage/Resources_fr.properties   |  2 +
 .../aggregate/ConcatenatedGridCoverage.java        | 34 ++++++++++++-
 .../aggregate/ConcatenatedGridResource.java        |  9 +++-
 .../storage/aggregate/CoverageAggregator.java      | 59 +++++++++++++++++++++-
 .../sis/internal/storage/aggregate/GridSlice.java  |  8 +--
 .../storage/aggregate/GridSliceLocator.java        | 24 +++++++++
 .../storage/aggregate/GroupByTransform.java        | 14 ++++-
 .../internal/storage/aggregate/MergeStrategy.java  | 50 ++++++++++++++++++
 10 files changed, 203 insertions(+), 9 deletions(-)

diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
index 5934ebb244..448986964e 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
@@ -326,6 +326,16 @@ public final class Resources extends IndexedResourceBundle 
{
          */
         public static final short NoCommonFeatureType = 75;
 
+        /**
+         * Index {1} in dimension “{0}” maps to {2} slices.
+         */
+        public static final short NoSliceMapped_3 = 79;
+
+        /**
+         * Extent in dimension “{0}” should be a slice, but {1} cells were 
specified.
+         */
+        public static final short NoSliceSpecified_2 = 80;
+
         /**
          * No directory of resources found at “{0}”.
          */
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
index c561b2bb2f..8e97fbf6c7 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
@@ -72,6 +72,8 @@ MarkNotSupported_1                = Marks are not supported 
on \u201c{0}\u201d s
 MissingResourceIdentifier_1       = Resource \u201c{0}\u201d does not have an 
identifier.
 MissingSchemeInURI_1              = Missing scheme in \u201c{0}\u201d URI.
 NoCommonFeatureType               = No feature type is common to all the 
features to aggregate.
+NoSliceMapped_3                   = Index {1} in dimension \u201c{0}\u201d 
maps to {2} slices. This error can be avoided by specifying a merge strategy.
+NoSliceSpecified_2                = Extent in dimension \u201c{0}\u201d should 
be a slice, but {1} cells were specified.
 NoSuchResourceDirectory_1         = No directory of resources found at 
\u201c{0}\u201d.
 NoSuchResourceInAggregate_2       = Resource \u201c{1}\u201d is not part of 
aggregate \u201c{0}\u201d.
 NotAWritableFeatureSet_1          = Resource \u201c{0}\u201d is not a writable 
feature set.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
index 6c8d3708e5..ca2c3cc76a 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
@@ -77,6 +77,8 @@ MarkNotSupported_1                = Les marques ne sont pas 
support\u00e9es sur
 MissingResourceIdentifier_1       = La ressource \u00ab\u202f{0}\u202f\u00bb 
n\u2019a pas d\u2019identifiant.
 MissingSchemeInURI_1              = Il manque le sch\u00e9ma dans l\u2019URI 
\u00ab\u202f{0}\u202f\u00bb.
 NoCommonFeatureType               = Il n\u2019y a pas de type commun \u00e0 
toutes les entit\u00e9s \u00e0 agr\u00e9ger.
+NoSliceMapped_3                   = L\u2019index {1} dans la dimension 
\u00ab\u202f{0}\u202f\u00bb correspond \u00e0 {2} tranches. Cette erreur peut 
\u00eatre \u00e9vit\u00e9e en sp\u00e9cifiant une strat\u00e9gie de fusion.
+NoSliceSpecified_2                = La plage dans la dimension 
\u00ab\u202f{0}\u202f\u00bb devrait \u00eatre une tranche, mais {1} cellules 
ont \u00e9t\u00e9 sp\u00e9cifi\u00e9es.
 NoSuchResourceDirectory_1         = Aucun r\u00e9pertoire de ressources 
n\u2019a \u00e9t\u00e9 trouv\u00e9 \u00e0 l\u2019emplacement 
\u00ab\u202f{0}\u202f\u00bb.
 NoSuchResourceInAggregate_2       = La ressource \u00ab\u202f{1}\u202f\u00bb 
n\u2019est pas une partie de l\u2019agr\u00e9gat \u00ab\u202f{0}\u202f\u00bb.
 NotAWritableFeatureSet_1          = La ressource \u00ab\u202f{0}\u202f\u00bb 
n\u2019est pas un ensemble d\u2019entit\u00e9s accessibles en \u00e9criture.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridCoverage.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridCoverage.java
index 1a5a8d280f..c47d674021 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridCoverage.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridCoverage.java
@@ -85,6 +85,11 @@ final class ConcatenatedGridCoverage extends GridCoverage {
      */
     private final int startAt;
 
+    /**
+     * Algorithm to apply when more than one grid coverage can be found at the 
same grid index.
+     */
+    private final MergeStrategy strategy;
+
     /**
      * Creates a new aggregated coverage.
      *
@@ -108,6 +113,7 @@ final class ConcatenatedGridCoverage extends GridCoverage {
         this.ranges      = ranges;
         this.isConverted = source.isConverted;
         this.locator     = source.locator;
+        this.strategy    = source.strategy;
     }
 
     /**
@@ -124,6 +130,7 @@ final class ConcatenatedGridCoverage extends GridCoverage {
         this.request     = source.request;
         this.ranges      = source.ranges;
         this.locator     = source.locator;
+        this.strategy    = source.strategy;
         this.isConverted = converted;
     }
 
@@ -178,9 +185,32 @@ final class ConcatenatedGridCoverage extends GridCoverage {
         } else {
             extent = gridGeometry.getExtent();
         }
-        if (upper - lower != 1) {
-            throw new SubspaceNotSpecifiedException();
+        final int size = upper - lower;
+        if (size != 1) {
+            switch (strategy) {
+                default: {
+                    /*
+                     * Can not infer a slice. If the user specified a single 
slice but that slice
+                     * maps to more than one coverage, the error message tells 
that this problem
+                     * can be avoided by specifying a merge strategy.
+                     */
+                    final short message;
+                    final Object[] arguments;
+                    if (locator.isSlice(extent)) {
+                        message   = Resources.Keys.NoSliceMapped_3;
+                        arguments = new Object[] 
{locator.getDimensionName(extent), lower, size};
+                    } else {
+                        message   = Resources.Keys.NoSliceSpecified_2;
+                        arguments = new Object[] 
{locator.getDimensionName(extent), size};
+                    }
+                    throw new 
SubspaceNotSpecifiedException(Resources.format(message, arguments));
+                }
+            }
         }
+        /*
+         * Argument have been validated and slice has been located.
+         * If the coverage has not already been loaded, load it now.
+         */
         GridCoverage slice = slices[lower];
         if (slice == null) try {
             slice = resources[lower].read(request, 
ranges).forConvertedValues(isConverted);
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridResource.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridResource.java
index 0b5f48fa67..0f0c6c8f4f 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridResource.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/ConcatenatedGridResource.java
@@ -108,6 +108,11 @@ final class ConcatenatedGridResource extends 
AbstractGridCoverageResource implem
      */
     final GridSliceLocator locator;
 
+    /**
+     * Algorithm to apply when more than one grid coverage can be found at the 
same grid index.
+     */
+    final MergeStrategy strategy;
+
     /**
      * The envelope of this aggregate, or {@code null} if not yet computed.
      * May also be {@code null} if no slice declare an envelope, or if the 
union can not be computed.
@@ -143,7 +148,8 @@ final class ConcatenatedGridResource extends 
AbstractGridCoverageResource implem
                              final GridGeometry           domain,
                              final List<SampleDimension>  ranges,
                              final GridCoverageResource[] slices,
-                             final GridSliceLocator       locator)
+                             final GridSliceLocator       locator,
+                             final MergeStrategy          strategy)
     {
         super(listeners, false);
         this.name             = name;
@@ -151,6 +157,7 @@ final class ConcatenatedGridResource extends 
AbstractGridCoverageResource implem
         this.sampleDimensions = ranges;
         this.slices           = slices;
         this.locator          = locator;
+        this.strategy         = strategy;
         this.deferredLoading  = new long[Numerics.ceilDiv(slices.length, 
Long.SIZE)];
         for (final SampleDimension sd : ranges) {
             if (sd.forConvertedValues(true) != sd) {
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/CoverageAggregator.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/CoverageAggregator.java
index b16486ddbe..91d4292bbc 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/CoverageAggregator.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/CoverageAggregator.java
@@ -35,12 +35,31 @@ import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.GridCoverageResource;
 import org.apache.sis.storage.event.StoreListeners;
+import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.util.collection.BackingStoreException;
+import org.apache.sis.util.ArgumentChecks;
 
 
 /**
  * Creates a grid coverage resource from an aggregation of an arbitrary amount 
of other resources.
  *
+ * <div class="note"><b>Example:</b>
+ * a collection of {@link GridCoverage} instances may represent the same 
phenomenon
+ * (for example Sea Surface Temperature) over the same geographic area but at 
different dates and times.
+ * {@link CoverageAggregator} can be used for building a single data cube with 
a time axis.</div>
+ *
+ * All source coverages should share the same CRS and have the same ranges 
(sample dimensions).
+ * If this is not the case, then the source coverages will be grouped in 
different aggregates
+ * with an uniform CRS and set of ranges in each sub-aggregates.
+ *
+ * <h2>Multi-threading and concurrency</h2>
+ * All {@code add(…)} methods can be invoked concurrently from arbitrary 
threads.
+ * It is okay to load {@link GridCoverageResource} instances in parallel 
threads
+ * and add those resources to {@code CoverageAggregator} without 
synchronization.
+ * However the final {@link #build()} method is <em>not</em> thread-safe;
+ * that method shall be invoked from a single thread after all sources have 
been added
+ * and no more addition are in progress.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.3
  * @since   1.3
@@ -58,6 +77,13 @@ public final class CoverageAggregator extends 
Group<GroupBySample> {
      */
     private final Map<Set<Resource>, Queue<Aggregate>> aggregates;
 
+    /**
+     * Algorithm to apply when more than one grid coverage can be found at the 
same grid index.
+     *
+     * @see #getMergeStrategy()
+     */
+    private volatile MergeStrategy strategy;
+
     /**
      * Creates an initially empty aggregator.
      *
@@ -67,6 +93,7 @@ public final class CoverageAggregator extends 
Group<GroupBySample> {
     public CoverageAggregator(final StoreListeners listeners) {
         this.listeners = listeners;
         aggregates = new HashMap<>();
+        strategy = MergeStrategy.FAIL;
     }
 
     /**
@@ -114,7 +141,7 @@ public final class CoverageAggregator extends 
Group<GroupBySample> {
         final GridSlice slice = new GridSlice(resource);
         final List<GridSlice> slices;
         try {
-            slices = slice.getList(bySample.members).members;
+            slices = slice.getList(bySample.members, strategy).members;
         } catch (NoninvertibleTransformException e) {
             throw new DataStoreContentException(e);
         }
@@ -182,6 +209,36 @@ public final class CoverageAggregator extends 
Group<GroupBySample> {
         return Optional.empty();
     }
 
+    /**
+     * Returns the algorithm to apply when more than one grid coverage can be 
found at the same grid index.
+     * This is the most recent value set by a call to {@link 
#setMergeStrategy(MergeStrategy)},
+     * or {@link MergeStrategy#FAIL} by default.
+     *
+     * @return algorithm to apply for merging source coverages at the same 
grid index.
+     */
+    public MergeStrategy getMergeStrategy() {
+        return strategy;
+    }
+
+    /**
+     * Sets the algorithm to apply when more than one grid coverage can be 
found at the same grid index.
+     * The new strategy applies to the <em>next</em> coverages to be added;
+     * previously added coverage may or may not be impacted by this change 
(see below).
+     * Consequently this method should usually be invoked before to add the 
first coverage.
+     *
+     * <h4>Effect on previously added coverages</h4>
+     * The merge strategy of previously added coverages is not modified by 
this method call,
+     * except for coverages that become part of the same aggregated {@link 
GridCoverageResource}
+     * than a coverage added after this method call.
+     * In such case, the strategy set by the most recent call to {@code 
setMergeStrategy(…)} prevails.
+     *
+     * @param strategy new algorithm to apply for merging source coverages at 
the same grid index.
+     */
+    public void setMergeStrategy(final MergeStrategy strategy) {
+        ArgumentChecks.ensureNonNull("strategy", strategy);
+        this.strategy = strategy;
+    }
+
     /**
      * Builds a resource which is the aggregation or concatenation of all 
components added to this aggregator.
      * The returned resource will be an instance of {@link 
GridCoverageResource} if possible,
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSlice.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSlice.java
index 0c3e90dc4c..e3664625a6 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSlice.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSlice.java
@@ -129,11 +129,12 @@ final class GridSlice {
      * The CRS comparisons ignore metadata and transform comparisons ignore 
integer translations.
      * This method takes a synchronization lock on the given list.
      *
-     * @param  groups  the list where to search for a group.
+     * @param  groups    the list where to search for a group.
+     * @param  strategy  algorithm to apply when more than one grid coverage 
can be found at the same grid index.
      * @return group of objects associated to the given transform (never null).
      * @throws NoninvertibleTransformException if the transform is not 
invertible.
      */
-    final GroupByTransform getList(final List<GroupByCRS<GroupByTransform>> 
groups)
+    final GroupByTransform getList(final List<GroupByCRS<GroupByTransform>> 
groups, final MergeStrategy strategy)
             throws NoninvertibleTransformException
     {
         final MathTransform gridToCRS = 
geometry.getGridToCRS(PixelInCell.CELL_CORNER);
@@ -144,10 +145,11 @@ final class GridSlice {
                 final Matrix groupToSlice = c.linearTransform(crsToGrid);
                 if (groupToSlice != null && 
isIntegerTranslation(groupToSlice)) {
                     setOffset(MatrixSIS.castOrCopy(groupToSlice));
+                    c.strategy = strategy;
                     return c;
                 }
             }
-            final GroupByTransform c = new GroupByTransform(geometry, 
gridToCRS);
+            final GroupByTransform c = new GroupByTransform(geometry, 
gridToCRS, strategy);
             transforms.add(c);
             return c;
         }
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSliceLocator.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSliceLocator.java
index 1cc91e89f2..35d061ca53 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSliceLocator.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GridSliceLocator.java
@@ -21,11 +21,13 @@ import java.util.List;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.function.Function;
+import org.opengis.util.InternationalString;
 import org.opengis.referencing.datum.PixelInCell;
 import org.opengis.metadata.spatial.DimensionNameType;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.util.iso.Types;
 
 
 /**
@@ -190,4 +192,26 @@ final class GridSliceLocator {
         }
         return toIndex;
     }
+
+    /**
+     * Returns {@code true} if the grid extent in the search dimension is a 
slice of size 1.
+     *
+     * @param  sliceExtent  the extent to search.
+     * @return whether the extent is a slice in the search dimension.
+     */
+    final boolean isSlice(final GridExtent sliceExtent) {
+        return sliceExtent.getLow(searchDimension) == 
sliceExtent.getHigh(searchDimension);
+    }
+
+    /**
+     * Return the name of the extent axis in the search dimension.
+     *
+     * @param  extent  the extent from which to get an axis label.
+     * @return label for the search axis.
+     */
+    final String getDimensionName(final GridExtent extent) {
+        return extent.getAxisType(searchDimension)
+                .map(Types::getCodeTitle).map(InternationalString::toString)
+                .orElseGet(() -> String.valueOf(searchDimension));
+    }
 }
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GroupByTransform.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GroupByTransform.java
index 83dd19ccf5..a62efcedc7 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GroupByTransform.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/GroupByTransform.java
@@ -57,15 +57,24 @@ final class GroupByTransform extends Group<GridSlice> {
      */
     private final MathTransform gridToCRS;
 
+    /**
+     * Algorithm to apply when more than one grid coverage can be found at the 
same grid index.
+     * This is set at construction time and usually keep the same value after 
that point,
+     * unless {@link CoverageAggregator#setMergeStrategy(MergeStrategy)} is 
invoked again.
+     */
+    MergeStrategy strategy;
+
     /**
      * Creates a new group of objects associated to the given transform.
      *
      * @param  geometry   geometry of the grid coverage or resource.
      * @param  gridToCRS  value or {@code 
geometry.getGridToCRS(PixelInCell.CELL_CORNER)}.
+     * @param  strategy   algorithm to apply when more than one grid coverage 
can be found at the same grid index.
      */
-    GroupByTransform(final GridGeometry geometry, final MathTransform 
gridToCRS) {
+    GroupByTransform(final GridGeometry geometry, final MathTransform 
gridToCRS, final MergeStrategy strategy) {
         this.geometry  = geometry;
         this.gridToCRS = gridToCRS;
+        this.strategy  = strategy;
     }
 
     /**
@@ -148,6 +157,7 @@ final class GroupByTransform extends Group<GridSlice> {
         final GridCoverageResource[] slices  = new GridCoverageResource[n];
         final GridSliceLocator       locator = new GridSliceLocator(members, 
dimensions[0], slices);
         final GridGeometry           domain  = locator.union(geometry, 
members, GridSlice::getGridExtent);
-        return new ConcatenatedGridResource(getName(parentListeners), 
parentListeners, domain, ranges, slices, locator);
+        return new ConcatenatedGridResource(getName(parentListeners), 
parentListeners,
+                                            domain, ranges, slices, locator, 
strategy);
     }
 }
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/MergeStrategy.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/MergeStrategy.java
new file mode 100644
index 0000000000..4578097af5
--- /dev/null
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/aggregate/MergeStrategy.java
@@ -0,0 +1,50 @@
+/*
+ * 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.aggregate;
+
+import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.grid.GridCoverage;
+import org.apache.sis.coverage.SubspaceNotSpecifiedException;
+
+
+/**
+ * Algorithm to apply when more than one grid coverage can be found at the 
same grid index.
+ * A merge may happen if an aggregated coverage is created with {@link 
CoverageAggregator},
+ * and the extent of some source coverages are overlapping in the dimension to 
aggregate.
+ *
+ * <div class="note"><b>Example:</b>
+ * a collection of {@link GridCoverage} instances may represent the same 
phenomenon
+ * (for example Sea Surface Temperature) over the same geographic area but at 
different dates and times.
+ * {@link CoverageAggregator} can be used for building a single data cube with 
a time axis.
+ * But if two coverages have overlapping time ranges, and if an user request 
data in the overlapping region,
+ * then the aggregated coverages have more than one source coverages capable 
to provide the requested data.
+ * This enumeration specify how to handle this multiplicity.</div>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.3
+ * @since   1.3
+ * @module
+ */
+public enum MergeStrategy {
+    /**
+     * Do not perform any merge. It will cause a {@link 
SubspaceNotSpecifiedException} to be thrown by
+     * {@link GridCoverage#render(GridExtent)} if more than one source 
coverage is found for a specified slice.
+     *
+     * <p>This is the default strategy.</p>
+     */
+    FAIL
+}

Reply via email to