This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit b811a4f2602b8ff853d92797ae726a6638cda9da
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Jun 17 15:48:03 2026 +0200

    Add image size columns in `TileMatrixSetFormat`.
---
 .../apache/sis/storage/tiling/ImageTileMatrix.java | 10 ++++
 .../sis/storage/tiling/TileMatrixSetFormat.java    | 58 +++++++++++++++++-----
 .../apache/sis/gui/coverage/TileMatrixSetPane.java | 33 +++++++++---
 3 files changed, 83 insertions(+), 18 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImageTileMatrix.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImageTileMatrix.java
index 38d09e96e8..a50ed64ab1 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImageTileMatrix.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImageTileMatrix.java
@@ -232,6 +232,16 @@ final class ImageTileMatrix implements TileMatrix {
         return tilingScheme;
     }
 
+    /**
+     * Returns the extent of the resource.
+     *
+     * @return the grid extent.
+     * @throws DataStoreException if an error occurred while fecthing the grid 
geometry.
+     */
+    final GridExtent getResourceExtent() throws DataStoreException {
+        return resource.getGridGeometry().getExtent();
+    }
+
     /**
      * Returns the coverage, which is read when first needed.
      * This coverage uses deferred reading of tiles.
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 a3ccb5dfd4..321700a504 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
@@ -47,6 +47,7 @@ import org.apache.sis.util.internal.shared.Numerics;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTableFormat;
 import org.apache.sis.util.collection.BackingStoreException;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.IncompleteGridGeometryException;
@@ -58,11 +59,19 @@ import org.apache.sis.io.TableAppender;
 /**
  * Formats Tile Matrix Sets (<abbr>TMS</abbr>) in a tabular format.
  * This format assumes a monospaced font and a character encoding which 
supports the drawing of box characters,
- * such as <abbr>UTF</abbr>-8.
+ * such as <abbr>UTF</abbr>-8. The table contains one row for each Tile Matrix 
with the following columns:
+ *
+ * <ul>
+ *   <li>Tile matrix identifier</li>
+ *   <li>Resolution</li>
+ *   <li>Number of tiles</li>
+ *   <li>Tile size (if available)</li>
+ *   <li>Image size (if available)</li>
+ * </ul>
  *
  * <h2>Limitations</h2>
  * <ul>
- *   <li>The current implementation can only format tile matrices — parsing is 
supported.</li>
+ *   <li>The current implementation can only format tile matrices — parsing is 
unsupported.</li>
  *   <li>{@code TileMatrixSetFormat}, like most {@code java.text.Format} 
subclasses, is not thread-safe.</li>
  * </ul>
  *
@@ -96,6 +105,9 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
         /** The tile sizes in pixels. */
         final String[] tileSize;
 
+        /** The image sizes in pixels, or {@code null} if this information is 
not available. */
+        final String[] imageSize;
+
         /** The extent of the tiling scheme. */
         private final GridExtent tilingScheme;
 
@@ -104,11 +116,12 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
          *
          * @param  matrix         the matrix for which to store information.
          * @param  integerFormat  a number format configured for integer 
values.
+         * @param  caller         the object to notify in case of recoverable 
errors.
          * @throws BackingStoreException if an error occurred while extracting 
information.
          * @throws IncompleteGridGeometryException if the tiling scheme has 
not extent or resolution.
          *         Tile matrices with such tiling scheme should not have been 
constructed in first place.
          */
-        Row(final TileMatrix matrix, final NumberFormat integerFormat) {
+        Row(final TileMatrix matrix, final NumberFormat integerFormat, final 
TileMatrixSetFormat caller) {
             final GenericName id = matrix.getIdentifier();
             identifier = (id != null) ? id.toString() : "";
             resolution = matrix.getResolution();
@@ -123,6 +136,18 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
             for (int i=0; i<tileSize.length; i++) {
                 tileSize[i] = integerFormat.format(ts[i]);
             }
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            String[] imageSize = CharSequences.EMPTY_ARRAY;
+            if (matrix instanceof ImageTileMatrix) try {
+                final GridExtent extent = ((ImageTileMatrix) 
matrix).getResourceExtent();
+                imageSize = new String[extent.getDimension()];
+                for (int i=0; i<imageSize.length; i++) {
+                    imageSize[i] = integerFormat.format(extent.getSize(i));
+                }
+            } catch (DataStoreException | IncompleteGridGeometryException e) {
+                caller.addError(e);
+            }
+            this.imageSize = imageSize;
         }
 
         /**
@@ -268,10 +293,11 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
      *   <tr><td>{@code "resolutions"}</td> <td>{@code String[][]}</td> 
<td>Columns of the resolution of each Tile Matrix.</td></tr>
      *   <tr><td>{@code "tileCounts"}</td>  <td>{@code String[][]}</td> 
<td>Columns of the number of tiles of each Tile Matrix.</td></tr>
      *   <tr><td>{@code "tileSizes"}</td>   <td>{@code String[][]}</td> 
<td>Columns of the tile size of each Tile Matrix.</td></tr>
+     *   <tr><td>{@code "imageSizes"}</td>  <td>{@code String[][]}</td> 
<td>Columns of the image size (if available).</td></tr>
      *   <tr><td>{@code "gridAxes"}</td>    <td>{@code String[]}</td>   
<td>Name of grid axes.</td></tr>
      * </table>
      *
-     * The {@code "tileSizes"} property may be absent if not applicable.
+     * The {@code "tileSizes"} and {@code "imageSizes"} properties may be 
absent if not applicable.
      * Implementations other than the default implementation may also choose 
to add or remove more properties.
      *
      * <p>This method returns the number of rows in the table to format.
@@ -288,12 +314,13 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
      */
     public int formatTable(final Iterable<? extends TileMatrix> matrices, 
final Map<String, Object> addTo) {
         final var rows = new ArrayList<Row>();
-        int gridDimension = 0, sizeDimension = 0;
+        int gridDimension = 0, sizeDimension = 0, fullDimension = 0;
         final var integerFormat = (NumberFormat) getFormat(Long.class);
         for (final TileMatrix matrix : matrices) try {
-            final var row = new Row(matrix, integerFormat);
+            final var row = new Row(matrix, integerFormat, this);
             gridDimension = Math.max(gridDimension, row.tileCount.length);
-            sizeDimension = Math.max(sizeDimension, row.tileSize.length);
+            sizeDimension = Math.max(sizeDimension, row.tileSize .length);
+            fullDimension = Math.max(fullDimension, row.imageSize.length);
             rows.add(row);  // Add only on success.
         } catch (RuntimeException e) {
             addError(e);    // Skip the row. Next row will be tried.
@@ -304,6 +331,7 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
         final var resolutions = new String[ crsDimension][numRows];
         final var tileCounts  = new String[gridDimension][numRows];
         final var tileSizes   = new String[sizeDimension][numRows];
+        final var imageSizes  = new String[fullDimension][numRows];
         final var gridAxes    = new String[gridDimension];
         for (int j=0; j<numRows; j++) {
             final Row row = rows.get(j);
@@ -318,11 +346,15 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
             for (int i = Math.min(sizeDimension, row.tileSize.length); --i >= 
0;) {
                 tileSizes[i][j] = row.tileSize[i];
             }
+            for (int i = Math.min(fullDimension, row.imageSize.length); --i >= 
0;) {
+                imageSizes[i][j] = row.imageSize[i];
+            }
         }
-        if (numRows       != 0) addTo.put("identifiers", identifiers);
-        if (crsDimension  != 0) addTo.put("resolutions", resolutions);
-        if (gridDimension != 0) addTo.put("tileCounts",  tileCounts);
-        if (sizeDimension != 0) addTo.put("tileSizes",   tileSizes);
+        if (numRows       != 0) addTo.put("identifiers",  identifiers);
+        if (crsDimension  != 0) addTo.put("resolutions",  resolutions);
+        if (gridDimension != 0) addTo.put("tileCounts",   tileCounts);
+        if (sizeDimension != 0) addTo.put("tileSizes",    tileSizes);
+        if (fullDimension != 0) addTo.put("imageSizes",   imageSizes);
         for (int i=0; i<gridAxes.length; i++) {
             final String name = gridAxes[i];
             if (name != null && name.isBlank()) {
@@ -422,7 +454,8 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
         final var resolutions = (String[][]) properties.get("resolutions");
         final var tileCounts  = (String[][]) properties.get("tileCounts");
         final var tileSizes   = (String[][]) properties.get("tileSizes");
-        String[][][] columnGroups = {resolutions, tileCounts, tileSizes};
+        final var imageSizes  = (String[][]) properties.get("imageSizes");
+        String[][][] columnGroups = {resolutions, tileCounts, tileSizes, 
imageSizes};
         columnGroups = ArraysExt.resize(columnGroups, 
ArraysExt.removeNulls(columnGroups));
         for (final String[][] columns : columnGroups) {
             for (final String[] column : columns) {
@@ -440,6 +473,7 @@ public class TileMatrixSetFormat extends 
CompoundFormat<TileMatrixSet> {
         if (resolutions != null) 
table.append(vocabulary.getString(Vocabulary.Keys.Resolution)).nextColumn();
         if (tileCounts  != null) 
table.append(vocabulary.getString(Vocabulary.Keys.TileCount)) .nextColumn();
         if (tileSizes   != null) 
table.append(vocabulary.getString(Vocabulary.Keys.TileSize))  .nextColumn();
+        if (imageSizes  != null) 
table.append(vocabulary.getString(Vocabulary.Keys.ImageSize)) .nextColumn();
         table.appendHorizontalSeparator();
         for (int j=0; j<numRows; j++) {
             if (identifiers != null) {
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 8405bc5f12..1eddb69e74 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
@@ -139,6 +139,13 @@ public class TileMatrixSetPane extends Widget {
      */
     private final TableColumn<Row, String> tileSizeColumns;
 
+    /**
+     * The columns for the image size in each dimension.
+     * The number of columns is the number of grid dimensions.
+     * Values are {@link Integer}s, for formatted as {@link String}s by {@link 
TileMatrixSetFormat}.
+     */
+    private final TableColumn<Row, String> imageSizeColumns;
+
     /**
      * A row in the table of tile matrices shown by {@link #tileMatrices}.
      * The resolution, tile count and tile size are groups of columns.
@@ -162,11 +169,17 @@ public class TileMatrixSetPane extends Widget {
         final StringProperty[] tileCount;
 
         /**
-         * Tile size along each grid dimension.
+         * Tile size along each grid dimension of the tiles at this level.
          * They are the values to show in the group {@link #tileSizeColumns}.
          */
         final StringProperty[] tileSize;
 
+        /**
+         * Tile size along each grid dimension of the image at this level.
+         * They are the values to show in the group {@link #imageSizeColumns}.
+         */
+        final StringProperty[] imageSize;
+
         /**
          * Creates a new row for the given properties at the specified row 
index.
          */
@@ -175,21 +188,25 @@ public class TileMatrixSetPane extends Widget {
             final String[]   identifiers,
             final String[][] resolutions,
             final String[][] tileCounts,
-            final String[][] tileSizes)
+            final String[][] tileSizes,
+            final String[][] imageSizes)
         {
             identifier = new SimpleStringProperty(this, "identifier", 
identifiers == null ? null : identifiers[row]);
             resolution = new SimpleStringProperty[resolutions != null ? 
resolutions.length : 0];
             tileCount  = new SimpleStringProperty[tileCounts  != null ?  
tileCounts.length : 0];
             tileSize   = new SimpleStringProperty[tileSizes   != null ?   
tileSizes.length : 0];
+            imageSize  = new SimpleStringProperty[imageSizes  != null ?  
imageSizes.length : 0];
             Arrays.setAll(resolution, (i) -> new SimpleStringProperty(this, 
"resolution", resolutions[i][row]));
             Arrays.setAll(tileCount,  (i) -> new SimpleStringProperty(this, 
"tileCount",  tileCounts [i][row]));
             Arrays.setAll(tileSize,   (i) -> new SimpleStringProperty(this, 
"tileSize",   tileSizes  [i][row]));
+            Arrays.setAll(imageSize,  (i) -> new SimpleStringProperty(this, 
"imageSize",  imageSizes [i][row]));
         }
 
         /**
          * Returns the group of columns identified by the given index.
+         * Value 0 is reserved for identifier (not accepted by this method).
          *
-         * @param  groupIndex  1 for resolution, 2 for tile count or 3 for 
tile size. 0 is reserved for identifier.
+         * @param  groupIndex  1 for resolution, 2 for tile count, 3 for tile 
size, 4 for image size.
          * @return group of columns at the given index.
          */
         @SuppressWarnings("ReturnOfCollectionOrArrayField")
@@ -198,6 +215,7 @@ public class TileMatrixSetPane extends Widget {
                 case 1: return resolution;
                 case 2: return tileCount;
                 case 3: return tileSize;
+                case 4: return imageSize;
                 default: throw new AssertionError(groupIndex);
             }
         }
@@ -290,12 +308,13 @@ public class TileMatrixSetPane extends Widget {
             tileResolutionColumns = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.Resolution));
             tileCountColumns      = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.TileCount));
             tileSizeColumns       = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.TileSize));
+            imageSizeColumns      = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.ImageSize));
             identifier.setCellValueFactory(Row.IDENTIFIER_GETTER);
 
             tileMatrices = new TableView<>();
             tileMatrices.setEditable(false);
             
tileMatrices.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_SUBSEQUENT_COLUMNS);
-            tileMatrices.getColumns().setAll(List.of(identifier, 
tileResolutionColumns, tileCountColumns, tileSizeColumns));
+            tileMatrices.getColumns().setAll(List.of(identifier, 
tileResolutionColumns, tileCountColumns, tileSizeColumns, imageSizeColumns));
             GridPane.setHgrow(tileMatrices, Priority.ALWAYS);
             GridPane.setVgrow(tileMatrices, Priority.ALWAYS);
             GridPane.setColumnSpan(tileMatrices, 2);
@@ -456,9 +475,10 @@ public class TileMatrixSetPane extends Widget {
                     final var resolutions = (String[][]) 
properties.get("resolutions");
                     final var tileCounts  = (String[][]) 
properties.get("tileCounts");
                     final var tileSizes   = (String[][]) 
properties.get("tileSizes");
+                    final var imageSizes  = (String[][]) 
properties.get("imageSizes");
                     final var rows        = new Row[numRows];
-                    for (int i=0; i<rows.length; i++) {
-                        rows[i] = new Row(i, identifiers, resolutions, 
tileCounts, tileSizes);
+                    for (int i = 0; i < rows.length; i++) {
+                        rows[i] = new Row(i, identifiers, resolutions, 
tileCounts, tileSizes, imageSizes);
                     }
                     tileMatrices.getItems().setAll(rows);
                     final Row first = (rows.length != 0) ? rows[0] : null;
@@ -475,6 +495,7 @@ public class TileMatrixSetPane extends Widget {
                     };
                     addOrRemoveColumns(first, 2, tileCountColumns, headerText);
                     addOrRemoveColumns(first, 3, tileSizeColumns,  headerText);
+                    addOrRemoveColumns(first, 4, imageSizeColumns, headerText);
                     if (warning != null) {
                         reportError(warning);
                     }

Reply via email to