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 c425e58d03fe85716b0587cab0d0b2f806c9dc72
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Feb 26 12:16:02 2026 +0100

    Fix formatting of resolution in TileMatrixSet.
---
 .../sis/storage/tiling/TileMatrixSetFormat.java    | 16 ++++--
 .../apache/sis/util/internal/shared/Numerics.java  | 59 ++++++++++++++++++++++
 .../apache/sis/gui/coverage/TileMatrixSetPane.java |  2 +
 3 files changed, 72 insertions(+), 5 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
index 38049ca48a..2bc3e1e040 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
@@ -127,9 +127,9 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
 
         /**
          * Updates the axis name in the dimension <var>i</var> of the grid 
extent.
-         * This method verifies that all grid dimensions have the same name.
+         * This method verifies that grid dimensions in all rows have the same 
axis names.
          */
-        private final void searchCommonAxisName(final String[] gridAxes, final 
int i) {
+        private void searchCommonAxisName(final String[] gridAxes, final int 
i) {
             tilingScheme.getAxisType(i).ifPresent((axis) -> {
                 final String name = axis.identifier().orElseGet(() -> 
axis.name().toLowerCase(Locale.US));
                 final String current = gridAxes[i];
@@ -163,9 +163,15 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
                 final int n = 
Numerics.suggestFractionDigits(ArraysExt.resize(values, count));
                 format.setMinimumFractionDigits(n);
                 format.setMaximumFractionDigits(n);
-                for (final Row row : rows) {
-                    if (i < row.resolution.length) {
-                        row.formattedResolution[i] = 
format.format(row.resolution[i]);
+                final int column = i;   // Because lambda requires final 
values.
+                final String[] formatted = 
Numerics.formatAndTrimTrailingZeros(format, values.length, (j) -> {
+                    final double[] resolution = rows.get(j).resolution;
+                    return (column < resolution.length) ? resolution[column] : 
Double.NaN;
+                });
+                for (int j=0; j<values.length; j++) {
+                    final String[] resolution = 
rows.get(j).formattedResolution;
+                    if (i < resolution.length) {
+                        resolution[i] = formatted[j];
                     }
                 }
             }
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
index dae6a203b6..4062f1de00 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
@@ -18,9 +18,12 @@ package org.apache.sis.util.internal.shared;
 
 import java.util.Arrays;
 import java.text.Format;
+import java.text.NumberFormat;
 import java.text.DecimalFormat;
+import java.text.FieldPosition;
 import java.math.BigInteger;
 import java.util.function.BiFunction;
+import java.util.function.IntToDoubleFunction;
 import static java.lang.Math.min;
 import static java.lang.Math.max;
 import static java.lang.Math.abs;
@@ -652,6 +655,62 @@ public final class Numerics {
         return fractionDigitsForDelta(delta);
     }
 
+    /**
+     * Gets the character used for zero.
+     * If the given format is not a {@link DecimalFormat}, arbitrarily returns 
the white space.
+     *
+     * @param  format  the format for which to get the zero digit.
+     * @return the zero digit, or {@code ' '} if the format is not decimal.
+     */
+    private static char getZeroDigit(final Format format) {
+        return (format instanceof DecimalFormat) ? ((DecimalFormat) 
format).getDecimalFormatSymbols().getZeroDigit() : ' ';
+    }
+
+    /**
+     * Formats values then removes the same number of trailing zeros in the 
fraction digits of all values.
+     * For this method to be useful, the given format should use a fixed 
number of fraction digits.
+     * NaN and infinite values are formatted as usual but ignored in the 
removal of trailing zeros.
+     *
+     * @param  format  the format to use.
+     * @param  count   number of values to format.
+     * @param  values  provider of values to format.
+     * @return an array of length {@code count} with the formatted values.
+     */
+    public static String[] formatAndTrimTrailingZeros(final NumberFormat 
format, final int count, final IntToDoubleFunction values) {
+        final var  formatted     = new String[count];
+        final var  buffer        = new StringBuffer();
+        final var  fractionEnd   = new int[count];
+        final var  fractionField = new 
FieldPosition(NumberFormat.Field.FRACTION);
+        final char zeroDigit     = getZeroDigit(format);
+        int numberOfTrailingZeros = Integer.MAX_VALUE;
+        for (int i=0; i<count; i++) {
+            final double value = values.applyAsDouble(i);
+            String text = format.format(value, buffer, 
fractionField).toString();
+            formatted[i] = text;
+            if (numberOfTrailingZeros != 0 && Double.isFinite(value)) {
+                final int end    = fractionField.getEndIndex();
+                fractionEnd[i]   = end;
+                int firstNonZero = end;
+                final int start  = Math.max(fractionField.getBeginIndex(), end 
- numberOfTrailingZeros);
+                while (--firstNonZero > start) {
+                    if (text.charAt(firstNonZero) != zeroDigit) break;
+                }
+                numberOfTrailingZeros = Math.min(numberOfTrailingZeros, end - 
(firstNonZero + 1));
+            }
+            buffer.setLength(0);
+        }
+        if (numberOfTrailingZeros != 0) {
+            for (int i=0; i<count; i++) {
+                final int end = fractionEnd[i];
+                if (end != 0) {
+                    formatted[i] = buffer.append(formatted[i]).delete(end - 
numberOfTrailingZeros, end).toString();
+                    buffer.setLength(0);
+                }
+            }
+        }
+        return formatted;
+    }
+
     /**
      * Formats the given value with the given format, using scientific 
notation if needed.
      * This is a workaround for {@link DecimalFormat} not switching 
automatically to scientific notation for large numbers.
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
index df58248410..1da5ecb6ff 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
@@ -418,6 +418,8 @@ public class TileMatrixSetPane extends Widget {
      * The Tile Matrix Set properties are fetched in a background thread.
      *
      * @param  newValue  the Tile Matrix Set to use for building new content.
+     *
+     * @todo Defer the execution of the background task if this pane is not 
currently visible.
      */
     private void tileMatrixSetChanged(final TileMatrixSet newValue) {
         tileMatrices.getItems().clear();

Reply via email to