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 4f56a8248c305e9348aeb433968af2b7697cc9b1
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Nov 30 14:15:57 2021 +0100

    `CoverageCanvas` needs to take background value in account during 
"resample" operations.
---
 .../java/org/apache/sis/gui/map/StatusBar.java     |  8 ++++++-
 .../org/apache/sis/gui/map/ValuesUnderCursor.java  | 24 ++++++++++-----------
 .../sis/coverage/grid/ResampledGridCoverage.java   | 17 +++------------
 .../sis/internal/coverage/SampleDimensions.java    | 25 ++++++++++++++++++++++
 .../sis/internal/map/coverage/RenderingData.java   |  1 +
 5 files changed, 48 insertions(+), 27 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
index 75e74f2..ded8c86 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
@@ -126,6 +126,12 @@ public class StatusBar extends Widget implements 
EventHandler<MouseEvent> {
     private static final Insets PADDING = new Insets(5, 
Styles.SCROLLBAR_WIDTH, 6, 9);
 
     /**
+     * An arbitrary increase in size of the text field where sample values are 
shown.
+     * This is in case {@link #computeSizeOfSampleValues(String, Iterable)} 
underestimates the required size.
+     */
+    private static final int VALUES_PADDING = 9;
+
+    /**
      * The container of controls making the status bar.
      */
     private final HBox view;
@@ -1242,7 +1248,7 @@ public class StatusBar extends Widget implements 
EventHandler<MouseEvent> {
             if (!(width > 0)) {                 // May be 0 if canvas is not 
yet added to scene graph.
                 return false;
             }
-            sampleValues.setPrefWidth(width);
+            sampleValues.setPrefWidth(width + VALUES_PADDING);
         }
         return true;
     }
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java
index 6e8d291..3518f4c 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java
@@ -333,17 +333,17 @@ public abstract class ValuesUnderCursor {
                 // Same configuration than previous coverage.
                 return;
             }
-            final int n   = bands.size();
-            units         = new String[n];
-            sampleFormats = new NumberFormat[n];
-            outsideText = null;                     // Will be recomputed on 
next `evaluate(…)` call.
+            final int numBands = bands.size();
+            units         = new String[numBands];
+            sampleFormats = new NumberFormat[numBands];
+            outsideText   = null;               // Will be recomputed on next 
`evaluate(…)` call.
             /*
              * Only the first band is initially selected, unless the image has 
only 2 or 3 bands
              * in which case all bands are selected. An image with two bands 
is often giving the
              * (u,v) components of velocity vectors, which we want to keep 
together by default.
              */
             selectedBands.clear();
-            selectedBands.set(0, (n <= 3) ? n : 1, true);
+            selectedBands.set(0, (numBands <= 3) ? numBands : 1, true);
             nodata.clear();
             /*
              * Loop below initializes number formats and unit symbols for all 
bands, regardless
@@ -354,10 +354,10 @@ public abstract class ValuesUnderCursor {
             final Map<Unit<?>,String>       sharedSymbols = new HashMap<>();
             final Locale                    locale        = 
getLocale(property);
             final UnitFormat                unitFormat    = new 
UnitFormat(locale);
-            final CheckMenuItem[]           menuItems     = new 
CheckMenuItem[n];
-            for (int i=0; i<n; i++) {
-                final SampleDimension sd = bands.get(i);
-                menuItems[i] = createMenuItem(i, sd, locale);
+            final CheckMenuItem[]           menuItems     = new 
CheckMenuItem[numBands];
+            for (int b=0; b<numBands; b++) {
+                final SampleDimension sd = bands.get(b);
+                menuItems[b] = createMenuItem(b, sd, locale);
                 /*
                  * Build the list of texts to show for missing values. A 
coverage can have
                  * different NaN values representing different kind of missing 
values.
@@ -365,7 +365,7 @@ public abstract class ValuesUnderCursor {
                 for (final Category c : 
sd.forConvertedValues(true).getCategories()) {
                     final float value = ((Number) 
c.getSampleRange().getMinValue()).floatValue();
                     if (Float.isNaN(value)) try {
-                        nodata.putIfAbsent(toNodataKey(i, value), 
c.getName().toString(locale));
+                        nodata.putIfAbsent(toNodataKey(b, value), 
c.getName().toString(locale));
                     } catch (IllegalArgumentException e) {
                         recoverableException("changed", e);
                     }
@@ -374,7 +374,7 @@ public abstract class ValuesUnderCursor {
                  * Format in advance the units of measurement. If none, an 
empty string is used.
                  * Note: it is quite common that all bands use the same unit 
of measurement.
                  */
-                units[i] = sd.getUnits().map((unit) -> 
sharedSymbols.computeIfAbsent(unit,
+                units[b] = sd.getUnits().map((unit) -> 
sharedSymbols.computeIfAbsent(unit,
                                               (key) -> format(unitFormat, 
key))).orElse("");
                 /*
                  * Infer a number of fraction digits to use for the resolution 
of sample values in each band.
@@ -391,7 +391,7 @@ public abstract class ValuesUnderCursor {
                  *   - Key -1 is for default format with unspecified number of 
fraction digits.
                  *   - Key -2 is for scientific notation.
                  */
-                sampleFormats[i] = sharedFormats.computeIfAbsent(nf, 
(precision) -> {
+                sampleFormats[b] = sharedFormats.computeIfAbsent(nf, 
(precision) -> {
                     switch (precision) {
                         case 0:              return 
NumberFormat.getIntegerInstance(locale);
                         case DEFAULT_FORMAT: return 
NumberFormat.getNumberInstance(locale);
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
index 758678b..d095047 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ResampledGridCoverage.java
@@ -16,9 +16,7 @@
  */
 package org.apache.sis.coverage.grid;
 
-import java.util.List;
 import java.util.Arrays;
-import java.util.Optional;
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.awt.image.RenderedImage;
@@ -32,10 +30,10 @@ import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.image.DataType;
 import org.apache.sis.image.ImageProcessor;
-import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.internal.feature.Resources;
 import org.apache.sis.internal.util.DoubleDouble;
+import org.apache.sis.internal.coverage.SampleDimensions;
 import org.apache.sis.internal.referencing.DirectPositionView;
 import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
@@ -54,7 +52,7 @@ import org.apache.sis.util.Utilities;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   1.1
  * @module
  */
@@ -122,17 +120,8 @@ final class ResampledGridCoverage extends GridCoverage {
          * If no background value is declared, default is 0 for integer data or
          * NaN for floating point values.
          */
-        final List<SampleDimension> bands = getSampleDimensions();
-        final Number[] fillValues = new Number[bands.size()];
-        for (int i=fillValues.length; --i >= 0;) {
-            final SampleDimension band = bands.get(i);
-            final Optional<Number> bg = band.getBackground();
-            if (bg.isPresent()) {
-                fillValues[i] = bg.get();
-            }
-        }
         processor = processor.clone();
-        processor.setFillValues(fillValues);
+        
processor.setFillValues(SampleDimensions.backgrounds(getSampleDimensions()));
         changeOfCRS.setAccuracyOf(processor);
         imageProcessor = GridCoverageProcessor.unique(processor);
         final Dimension s = imageProcessor.getInterpolation().getSupportSize();
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/SampleDimensions.java
 
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/SampleDimensions.java
index 1881373..c0121ec 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/SampleDimensions.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/SampleDimensions.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.coverage;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.function.DoubleUnaryOperator;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.Category;
@@ -41,6 +42,30 @@ public final class SampleDimensions extends Static {
     }
 
     /**
+     * Returns the background values of all bands in the given list.
+     * The length of the returned array is the number of sample dimensions.
+     * If a sample dimension does not declare a background value, the 
corresponding array element is null.
+     *
+     * @param  bands  the bands for which to get background values, or {@code 
null}.
+     * @return the background values, or {@code null} if the given argument 
was null.
+     *         Otherwise the returned array is never null but may contain null 
elements.
+     */
+    public static Number[] backgrounds(final List<SampleDimension> bands) {
+        if (bands == null) {
+            return null;
+        }
+        final Number[] fillValues = new Number[bands.size()];
+        for (int i=fillValues.length; --i >= 0;) {
+            final SampleDimension band = bands.get(i);
+            final Optional<Number> bg = band.getBackground();
+            if (bg.isPresent()) {
+                fillValues[i] = bg.get();
+            }
+        }
+        return fillValues;
+    }
+
+    /**
      * Returns the {@code sampleFilters} arguments to use in a call to
      * {@link ImageProcessor#statistics ImageProcessor.statistics(…)} for 
excluding no-data values.
      * If the given sample dimensions are {@linkplain 
SampleDimension#converted() converted to units of measurement},
diff --git 
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
 
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
index d5ab73f..da8b572 100644
--- 
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
+++ 
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
@@ -278,6 +278,7 @@ public class RenderingData implements Cloneable {
      */
     @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
     public final void setCoverageSpace(final GridGeometry domain, final 
List<SampleDimension> ranges) {
+        processor.setFillValues(SampleDimensions.backgrounds(ranges));
         dataRanges   = ranges;      // Not cloned because already an 
unmodifiable list.
         dataGeometry = domain;
         /*

Reply via email to