You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2021/11/30 14:44:00 UTC
[sis] 02/03: `CoverageCanvas` needs to take background value in account during "resample" operations.
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 <ma...@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;
/*