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 2026/03/31 14:13:27 UTC

(sis) branch geoapi-3.1 updated (8c45b25f06 -> 76ac26bca2)

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

desruisseaux pushed a change to branch geoapi-3.1
in repository https://gitbox.apache.org/repos/asf/sis.git


    from 8c45b25f06 Merge branch 'geoapi-4.0' into geoapi-3.1
     add a42f8a7502 Safety against a possible integer overflow. Safety against precision loss.
     add 9cb97c64c3 Add a `GridExtent.reshape(long[])` method and use that for simplifying some code. Minor opportunistic reformating.
     add db9b5d4b64 feat(Geometry): prepare ArrayFactory interface to support Java or FFM allocation
     add ca6eba4f64 Move `TiledGridResource` and `TiledGridCoverage` to public API.
     add 2358b982a0 Replace `X_DIMENSION` and `Y_DIMENSION` constant by configurable fields. The intend it to reduce the risk of breaking API compatibility in future evolutions.
     add 5431859977 Adjust the API for future implementation of `TileMatrixSet`: - Simpler `TiledGridResource.read(…)` method to override. - Replace `ReshapedImage` constructors by static methods.
     add 81cee606d9 fix(Geometry): fix mesh primitive normal array larger then needed
     add 36ffa6594a fix(NetCDF): fix dimension mismatch between geometry coordinates and it's declared CRS
     add 3953075dd2 feat(NetCDF): improve moving features read performances, fix moving feature time property single value for features which are not trajectories
     add a1fa272d75 feat(Math): add Similarity transform interface and Similarity3D
     add f2101a867d Rework the way that native libraries are loaded for avoiding to destroy the same library many times when the library was loaded from a filename. This is needed for avoiding a JVM crash if the `GDALStoreProvider(Path)` constructor was invoked many times with the same path.
     add ebd3ddab59 Renamed `TiledGridResource` as `TiledGridCoverageResource`.
     add 4d1a8092ea Initial implementation of the `TileMatrixSet` interface. Tests are still superficial for now.
     add beda4a8939 Add a verification of the "untiled.tiff" image created for testing purposes in the previous commit.
     add 8f90281df1 Make the test more stable by avoiding a dependency to the EPSG database which may or may not be present.
     add acd0b93002 Provide a better error message when an image cannot be rendered because of an invalid "grid to CRS" transform.
     add bfedee8a7b Delegate to `WritablePixelIterator` the work of setting sample values from `IntBinaryOperator`.
     add de19b988f9 Finer-grain detection of when the `CoordinateOperation` can be cached for a pair of CRS. In particular, we now detect the case when the Area Of Interest (AOI) has not been used. It covers a lot of cases, in particular map projections from grid geometry to target CRS.
     add 17ef8c51f8 Retrofit the pyramid system of the GeoTIFF reader into the pyramid system of `TileMatrixSet`.
     add 7602b6cb17 feat(JavaFx): add a simple tile matrix set panel in CoverageExplorer
     add 32af8e44e5 Implement `ImagePyramid.toString()` for easier debugging. Use that string representation for now in the widget.
     add d5d6c59c48 Adjust the handling of `Locale` in `TiledGridCoverage`. Add a check of whether a `ComputedImage` tile is in error.
     add 5c3f12c80d Replace the raw text in the "Tiling" pane by a `TableView`.
     add d324b2e6bc feat(Geometry): implement Java array factory builder, factorize array code, prepare FFM array factory classes
     add 7c3fba2ec4 feat(Geometry): add scene model as geometry aggregation tree
     add f7fc74b400 Reuse the code of `TileMatrixSet.toString()` in the JavaFX widget. It produces a table easier to read.
     add 8546d59b4e doc(Geometry): document scene sampler
     add 7819f1feed feat(Geometry): merge geometry interfaces defined in different sections of ISO-19107
     add 8d27cdfb79 chore(Geometry): regroup geometry operations (Delaunay,GreedyInsert,EarClipping,TextureAtlas) in the operation package
     add a48ace0b26 Fix an `IndexOutOfBoundsException`.
     add c425e58d03 Fix formatting of resolution in TileMatrixSet.
     add 50b842aae4 feat(Geometry): review affine,matrix,similarity transforms. Follow the same pattern as Tuple and Vector, prepare Transform interface for Vector API and HAT Kernels
     add ad1fce0356 feat(Geometry): math Matrix extends geoapi Matrix, cleaning Similarity classes
     add 09c39185cf feat(Geometry): add scene animation classes
     add 6bd8f4811a feat(Geometry): add readonly super interface for Tuple,Vector,Matrix,Affine,Similarity
     add 133d1e5b49 feat(Geometry): replace Affine.toMatrix(buffer) by Matrix.setFromAffine(affine)
     add d5ff44456b Fix version of visual indications of which tiles are loaded in the JavaFX application.
     add 517b8edb7e feat(Math): remove several matrix static methods, now part of matrix classes
     add feb9fe9c8a Requires PostgreSQL 18 instead of 15 for enabling the use of collation.
     add 6aab23a159 chore(geoapi): update geoapi submodule
     add cf8c06ee86 feat(Geometry): add shortcut methods on Similarity
     add e99ccc798a Fix wrong tooltip associated to button for switching between grid coverage visual and table of values. Opportunistic documentation fixes.
     add d22fd8761f Provides a message saying that a CRS is missing instead of letting the exception propagate.
     add 0d285f701b Fix a ClassCastException in the result of optimizing an `equal` filter when the operands are two Boolean values.
     add 27ce7088b0 For an expression such as `equal(function("isNaN", …), literal(true))`, simplify to a more direct filter such as `function("isNaN", …)`.
     add a3003a5d58 Pyramid levels should be ordered from coarsest to finest resolution. https://issues.apache.org/jira/browse/SIS-628
     add c6225542f4 Rename `GridCoverageResource.getResolutions()` as `getAvailableResolutions()`. Keep the old method as a deprecated method. This is for compatibility.
     add 433c27f0fd Use shorter name in `TileMatrixSet` identifier. The identifier now hides the image identifier.
     add d38375dcb3 Consolidation of `ResourceTree` making a better usage of JavaFX events. This work is needed for reusing some properties in a future widget for configuring map items.
     add e49c660ef2 Adjustment in documentation, formatting and checks for null values. Removal of a new method which is not going to be used after all.
     add 028ac1be08 Allows `Containers.derivedList(…)` to return a list which supports addition of elements.
     add 86bff97aa0 Avoid misleading classname as display name of a data store.
     add 48633f0377 Adds a "Layers" panel and move the "Visual indication of tile loading" checkbox as a map item. This is the beginning of a `MapContextView` widget as a tree view with a configuration panel.
     add 14a89a39bc Move the widget for configuring the isoline as a `MapItem` to show in `MapContextView`.
     add a3b8326446 Move to `MapContextview` the widgets controlling the coverage appearence. Move to the status bar the label which was showing the CRS name.
     add 3a021d2345 Consolidation of the handling of CRS shown in the status bar.
     new 76ac26bca2 Merge branch 'geoapi-4.0' into geoapi-3.1. Contains (non-exhaustive list):

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../sis/coverage/grid/ClippedGridCoverage.java     |   3 +-
 .../org/apache/sis/coverage/grid/GridCoverage.java |  12 +-
 .../apache/sis/coverage/grid/GridCoverage2D.java   |   3 +-
 .../sis/coverage/grid/GridCoverageBuilder.java     |  53 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |   2 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   |  61 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |  24 +-
 .../main/org/apache/sis/feature/FeatureFormat.java |   8 +-
 .../feature/internal/shared/MovingFeatures.java    |  28 +-
 .../org/apache/sis/filter/ComparisonFilter.java    | 141 ++++-
 .../main/org/apache/sis/filter/LogicalFilter.java  |  15 +-
 .../main/org/apache/sis/filter/Optimization.java   |   2 +-
 .../sis/filter/base/BinaryFunctionWidening.java    |   3 +-
 .../apache/sis/filter/math/FilteringFunction.java  |  62 ++
 .../main/org/apache/sis/filter/math/Predicate.java |  28 +-
 .../main/org/apache/sis/image/BandedIterator.java  |  23 +
 .../main/org/apache/sis/image/ComputedImage.java   |  20 +-
 .../main/org/apache/sis/image/ComputedTiles.java   |  26 +-
 .../main/org/apache/sis/image/ImageProcessor.java  |   4 +-
 .../main/org/apache/sis/image/PlanarImage.java     |   2 +-
 .../apache/sis/image/WritablePixelIterator.java    |  50 +-
 .../sis/image/internal/shared/ReshapedImage.java   | 128 ++++-
 .../main/org/apache/sis/image/package-info.java    |   2 +-
 .../sis/coverage/grid/ClippedGridCoverageTest.java |   1 +
 .../apache/sis/coverage/grid/GridExtentTest.java   |  10 +-
 .../apache/sis/filter/ComparisonFilterTest.java    |  98 ++--
 .../apache/sis/filter/DynamicOptimizationTest.java |  19 +
 .../image/internal/shared/ReshapedImageTest.java   |  15 +-
 .../iso/extent/NotSpatioTemporalException.java     |   4 +-
 .../metadata/sql/internal/shared/ScriptRunner.java |   2 +-
 .../org.apache.sis.portrayal/main/module-info.java |   2 +-
 .../coverage/MultiResolutionCoverageLoader.java    |  46 +-
 .../org/apache/sis/map/coverage/RenderingData.java |  53 +-
 .../org/apache/sis/map/internal}/Resources.java    |  88 +--
 .../apache/sis/map/internal}/Resources.properties  |  12 +-
 .../org/apache/sis/map}/internal/Resources_en.java |   2 +-
 .../org/apache/sis/map}/internal/Resources_fr.java |   2 +-
 .../sis/map/internal/Resources_fr.properties}      |  17 +-
 .../org/apache/sis/map}/internal/package-info.java |   3 +-
 .../main/org/apache/sis/portrayal/Observable.java  |   2 -
 .../org/apache/sis/portrayal/PlanarCanvas.java     |   7 +-
 .../MultiResolutionCoverageLoaderTest.java         |  18 +-
 .../main/org/apache/sis/geometry/Shapes2D.java     |   2 +-
 .../main/org/apache/sis/referencing/CommonCRS.java |   8 +-
 .../referencing/internal/shared/WKTUtilities.java  |   4 +-
 .../operation/CoordinateOperationContext.java      |  31 +-
 .../operation/CoordinateOperationFinder.java       |  30 +-
 .../operation/CoordinateOperationRegistry.java     |  63 +-
 .../DefaultCoordinateOperationFactory.java         |  58 +-
 .../referencing/operation/SubOperationInfo.java    |   8 +-
 .../sis/referencing/operation/matrix/Matrices.java |   4 +-
 .../sis/referencing/operation/package-info.java    |   2 +-
 .../operation/transform/PassThroughTransform.java  |   2 +-
 .../main/module-info.java                          |   2 +-
 .../sis/storage/geotiff/CompressedSubset.java      |  18 +-
 .../org/apache/sis/storage/geotiff/DataCube.java   |  65 +--
 .../org/apache/sis/storage/geotiff/DataSubset.java |  36 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |   2 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    | 218 +++++--
 .../sis/storage/geotiff/MultiResolutionImage.java  | 286 ---------
 .../org/apache/sis/storage/geotiff/Reader.java     |  22 +-
 .../apache/sis/storage/geotiff/package-info.java   |   2 +-
 .../sis/storage/geotiff/GeoTiffStoreTest.java      |  56 +-
 .../org/apache/sis/storage/geotiff/ReaderTest.java | 124 ++++
 .../org/apache/sis/storage/geotiff/WriterTest.java |   5 +-
 .../org/apache/sis/storage/geotiff/untiled.tiff    | Bin 0 -> 2284 bytes
 .../apache/sis/storage/netcdf/base/FeatureSet.java |  62 +-
 .../sis/storage/netcdf/base/RasterResource.java    |   2 +
 .../org/apache/sis/io/stream/ChannelDataInput.java |   2 +-
 .../sis/storage/AbstractGridCoverageResource.java  |  82 ++-
 .../org/apache/sis/storage/CoverageSubset.java     |  11 +-
 .../main/org/apache/sis/storage/DataStore.java     |  18 +-
 .../apache/sis/storage/GridCoverageResource.java   |  41 +-
 .../main/org/apache/sis/storage/Resource.java      |   4 +-
 .../org/apache/sis/storage/StorageConnector.java   |  25 +-
 .../sis/storage/UnsupportedQueryException.java     |   1 +
 .../aggregate/BandAggregateGridResource.java       |   4 +-
 .../aggregate/ConcatenatedGridResource.java        |  12 +-
 .../apache/sis/storage/aggregate/GridSlice.java    |  12 +-
 .../sis/storage/aggregate/GridSliceLocator.java    |   5 +-
 .../sis/storage/base/GridResourceWrapper.java      |   6 +-
 .../main/org/apache/sis/storage/csv/Store.java     |  13 +-
 .../org/apache/sis/storage/event/StoreEvent.java   |   2 +-
 .../apache/sis/storage/event/StoreListeners.java   |  14 +-
 .../org/apache/sis/storage/event/package-info.java |   4 +-
 .../apache/sis/storage/image/SingleImageStore.java |   6 +-
 .../storage/image/WritableSingleImageStore.java    |   4 +-
 .../org/apache/sis/storage/internal/Resources.java |   5 +
 .../sis/storage/internal/Resources.properties      |   1 +
 .../sis/storage/internal/Resources_fr.properties   |   1 +
 .../apache/sis/storage/tiling/ImagePyramid.java    | 472 +++++++++++++++
 .../apache/sis/storage/tiling/ImageTileMatrix.java | 532 +++++++++++++++++
 .../apache/sis/storage/tiling/IterationDomain.java | 221 +++++++
 .../main/org/apache/sis/storage/tiling/Tile.java   |   4 +-
 .../org/apache/sis/storage/tiling/TileMatrix.java  |  11 +-
 .../apache/sis/storage/tiling/TileMatrixSet.java   |  12 +-
 .../sis/storage/tiling/TileMatrixSetFormat.java    | 524 +++++++++++++++++
 .../apache/sis/storage/tiling/TileReadEvent.java   | 234 ++++++++
 .../org/apache/sis/storage/tiling/TileStatus.java  |   2 +-
 .../{base => tiling}/TiledDeferredImage.java       |  21 +-
 .../{base => tiling}/TiledGridCoverage.java        | 500 ++++++++++------
 .../TiledGridCoverageResource.java}                | 599 +++++++++++++++++--
 .../apache/sis/storage/tiling/TiledResource.java   |   4 +-
 .../apache/sis/storage/tiling/package-info.java    |  10 +-
 .../org/apache/sis/storage/CoverageQueryTest.java  |   8 +-
 .../storage/MemoryGridCoverageResourceTest.java    |   6 +-
 .../sis/storage/test/CoverageReadConsistency.java  |   2 +-
 .../main/org/apache/sis/io/TableAppender.java      |  16 +-
 .../main/org/apache/sis/io/TabularFormat.java      |   4 +-
 .../main/org/apache/sis/io/package-info.java       |   2 +-
 .../main/org/apache/sis/math/DecimalFunctions.java |  29 +-
 .../main/org/apache/sis/math/NumberType.java       |   2 +-
 .../main/org/apache/sis/math/Vector.java           |   2 +-
 .../main/org/apache/sis/util/ArgumentChecks.java   |  26 +-
 .../main/org/apache/sis/util/collection/Cache.java |   4 +-
 .../org/apache/sis/util/collection/Containers.java |  30 +-
 .../apache/sis/util/collection/DerivedList.java    |  31 +-
 .../sis/util/collection/WeakValueHashMap.java      |   6 +-
 .../sis/util/collection/WritableDerivedList.java   | 143 +++++
 .../sis/util/internal/shared/AbstractMap.java      |   2 +-
 .../apache/sis/util/internal/shared/Numerics.java  | 118 +++-
 .../org/apache/sis/util/resources/Vocabulary.java  |  20 +
 .../sis/util/resources/Vocabulary.properties       |   4 +
 .../sis/util/resources/Vocabulary_fr.properties    |   4 +
 .../org/apache/sis/math/DecimalFunctionsTest.java  |  32 +-
 .../{DerivedSetTest.java => DerivedListTest.java}  |  66 +--
 .../apache/sis/util/collection/DerivedMapTest.java |   1 +
 .../apache/sis/util/collection/DerivedSetTest.java |   1 +
 .../BilinearGrid.java                              |   3 +-
 .../{parametriccurvesurfaces => }/Cone.java        |   4 +-
 .../{parametriccurvesurfaces => }/Cylinder.java    |   4 +-
 .../main/org/apache/sis/geometries/Geometries.java |  24 +-
 .../ParametricCurveSurface.java                    |   2 +-
 .../apache/sis/geometries/{rhumb => }/Rhumb.java   |   2 +-
 .../main/org/apache/sis/geometries/Sphere.java     |  66 ++-
 .../apache/sis/geometries/conicsurfaces/Cone.java  |  26 -
 .../sis/geometries/conicsurfaces/Cylinder.java     |  26 -
 .../sis/geometries/conicsurfaces/Sphere.java       |  26 -
 .../apache/sis/geometries/math/AbstractAffine.java | 163 ++++++
 .../apache/sis/geometries/math/AbstractArray.java  |  21 +-
 .../apache/sis/geometries/math/AbstractCursor.java |   2 +-
 .../apache/sis/geometries/math/AbstractMatrix.java | 636 +++++++++++++++++++++
 .../sis/geometries/math/AbstractSimilarity.java    | 329 +++++++++++
 .../apache/sis/geometries/math/AbstractTuple.java  |   4 +-
 .../org/apache/sis/geometries/math/Affine.java     | 122 ++++
 .../org/apache/sis/geometries/math/Affine1D.java   | 161 ++++++
 .../org/apache/sis/geometries/math/Affine2D.java   | 226 ++++++++
 .../org/apache/sis/geometries/math/Affine3D.java   | 365 ++++++++++++
 .../org/apache/sis/geometries/math/Affine4D.java   | 482 ++++++++++++++++
 .../org/apache/sis/geometries/math/AffineND.java   |  99 ++++
 .../org/apache/sis/geometries/math/Affines.java}   |  22 +-
 .../main/org/apache/sis/geometries/math/Array.java |  30 +-
 .../sis/geometries/math/ArrayConcatenated.java     |  11 +-
 .../apache/sis/geometries/math/ArrayFactory.java   | 278 +++++++++
 .../sis/geometries/math/ArrayFactoryFFM.java       | 489 ++++++++++++++++
 .../{ArrayMemory.java => ArrayFactoryJava.java}    | 428 ++++----------
 .../sis/geometries/math/ArraySpliterator.java      |   6 +-
 .../sis/geometries/math/ArrayUnmodifiable.java     |  11 +-
 .../org/apache/sis/geometries/math/Cursor.java     |   2 +-
 .../sis/geometries/math/CursorUnmodifiable.java    |   8 +-
 .../main/org/apache/sis/geometries/math/Maths.java |  32 +-
 .../org/apache/sis/geometries/math/Matrices.java   | 338 +----------
 .../org/apache/sis/geometries/math/Matrix.java     | 137 ++++-
 .../org/apache/sis/geometries/math/Matrix2D.java   | 214 ++++++-
 .../org/apache/sis/geometries/math/Matrix3D.java   | 471 ++++++++++++++-
 .../org/apache/sis/geometries/math/Matrix4D.java   | 470 +++++++++++++--
 .../org/apache/sis/geometries/math/MatrixND.java   | 477 ++++++++++++++++
 .../org/apache/sis/geometries/math/NDArray.java    |  15 +-
 .../org/apache/sis/geometries/math/NDArrays.java   |  83 +--
 .../org/apache/sis/geometries/math/Quaternion.java |  53 +-
 .../apache/sis/geometries/math/Quaternions.java    |   2 +-
 .../org/apache/sis/geometries/math/ReadOnly.java   | 592 +++++++++++++++++++
 .../org/apache/sis/geometries/math/Similarity.java | 200 +++++++
 .../apache/sis/geometries/math/Similarity3D.java   | 197 +++++++
 .../apache/sis/geometries/math/SimilarityND.java   | 195 +++++++
 .../sis/geometries/math/SimplifiedTransform.java   | 106 ++++
 .../org/apache/sis/geometries/math/Transform.java  | 134 +++++
 .../{CursorUnmodifiable.java => Transform1D.java}  |  54 +-
 .../main/org/apache/sis/geometries/math/Tuple.java | 237 +-------
 .../sis/geometries/math/TupleUnmodifiable.java     |  24 +-
 .../org/apache/sis/geometries/math/Vector.java     |  93 +--
 .../org/apache/sis/geometries/math/Vector1D.java   |  26 +-
 .../org/apache/sis/geometries/math/Vector2D.java   |  26 +-
 .../org/apache/sis/geometries/math/Vector3D.java   |  31 +-
 .../org/apache/sis/geometries/math/Vector4D.java   |  42 +-
 .../org/apache/sis/geometries/math/VectorND.java   |  63 +-
 .../org/apache/sis/geometries/math/Vectors.java    |  30 +-
 .../apache/sis/geometries/math/package-info.java   |  20 +-
 .../apache/sis/geometries/mesh/MeshPrimitive.java  |  14 +-
 .../geometries/operation/GeometryOperations.java   |  10 +-
 .../{ => operation}/simplify/TextureAtlas.java     |   2 +-
 .../simplify/greedyinsert/Edge.java                |   2 +-
 .../simplify/greedyinsert/TINBuilder.java          |   2 +-
 .../simplify/greedyinsert/TinDistance.java         |   2 +-
 .../simplify/greedyinsert/WTriangle.java           |   8 +-
 .../{ => operation}/triangulate/EarClipping.java   |  18 +-
 .../triangulate/delaunay/Delaunay.java             |   2 +-
 .../triangulate/delaunay/OrientedEdge.java         |   2 +-
 .../triangulate/delaunay/OrientedTriangle.java     |   2 +-
 .../geometries/parametriccurvesurfaces/Sphere.java |  30 -
 .../processor/spatialedition/ToPrimitive.java      |   2 +-
 .../apache/sis/geometries/scene/Animation.java}    |  56 +-
 .../sis/geometries/scene/AnimationSampler.java}    |  52 +-
 .../org/apache/sis/geometries/scene/Camera.java    | 242 ++++++++
 .../org/apache/sis/geometries/scene/Material.java  | 627 ++++++++++++++++++++
 .../org/apache/sis/geometries/scene/Model.java     | 216 +++++++
 .../apache/sis/geometries/scene/MorphTarget.java   | 110 ++++
 .../org/apache/sis/geometries/scene/Sampler.java   | 172 ++++++
 .../org/apache/sis/geometries/scene/SceneNode.java | 510 +++++++++++++++++
 .../{math/AbstractArray.java => scene/Skin.java}   |  73 ++-
 .../org/apache/sis/geometries/scene/Surface.java   | 117 ++++
 .../org/apache/sis/geometries/scene/Texture.java   | 142 +++++
 .../apache/sis/geometries/scene}/package-info.java |  12 +-
 .../geometries/splinesurfaces/BSplineSurface.java  |   2 +-
 .../apache/sis/geometries/math/ArrayNbTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNdTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNfTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNiTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNlTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNsTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNubTest.java   |   2 +-
 .../apache/sis/geometries/math/ArrayNuiTest.java   |   2 +-
 .../apache/sis/geometries/math/ArrayNusTest.java   |   2 +-
 .../apache/sis/geometries/math/NDArraysTest.java   |   4 +-
 .../apache/sis/geometries/math/QuaternionTest.java |  35 +-
 .../{ => operation}/simplify/TextureAtlasTest.java |   2 +-
 .../triangulate/delaunay/DelaunayTest.java         |   2 +-
 .../triangulate/delaunay/OrientedEdgeTest.java     |   2 +-
 .../main/org/apache/sis/map/MapItem.java           |   8 +-
 .../apache/sis/storage/geoheif/FromImageIO.java    |   9 +-
 .../main/org/apache/sis/storage/geoheif/Image.java |   3 +-
 .../apache/sis/storage/geoheif/ImageResource.java  |  34 +-
 .../src/org.apache.sis.gui/main/module-info.java   |   2 +-
 .../main/org/apache/sis/gui/Widget.java            |   8 +-
 .../apache/sis/gui/controls/FormatApplicator.java  |   6 +-
 .../apache/sis/gui/controls/SyncWindowList.java    |   6 +-
 .../apache/sis/gui/controls/ValueColorMapper.java  |  12 +-
 .../apache/sis/gui/coverage/BandRangeTable.java    |   8 +-
 .../apache/sis/gui/coverage/CoverageCanvas.java    | 335 +++++++++--
 .../apache/sis/gui/coverage/CoverageControls.java  | 155 +++--
 .../apache/sis/gui/coverage/CoverageExplorer.java  |  36 +-
 .../apache/sis/gui/coverage/CoverageStyling.java   |  16 +-
 .../apache/sis/gui/coverage/GridSliceSelector.java |  12 +-
 .../sis/gui/coverage/ImagePropertyExplorer.java    |   6 +-
 ...IsolineRenderer.java => IsolineController.java} |  82 ++-
 .../apache/sis/gui/coverage/StyleController.java   | 173 ++++++
 .../sis/gui/coverage/StyledRenderingData.java      |   6 +-
 .../apache/sis/gui/coverage/TileMatrixSetPane.java | 499 ++++++++++++++++
 .../apache/sis/gui/coverage/ViewAndControls.java   |  22 +-
 .../org/apache/sis/gui/coverage/package-info.java  |   2 +-
 .../main/org/apache/sis/gui/dataset/LogViewer.java |   5 +-
 .../org/apache/sis/gui/dataset/ResourceCell.java   | 138 +++--
 .../apache/sis/gui/dataset/ResourceExplorer.java   |  52 +-
 .../org/apache/sis/gui/dataset/ResourceItem.java   | 178 ++++--
 .../org/apache/sis/gui/dataset/ResourceTree.java   |  50 +-
 .../org/apache/sis/gui/dataset/RootResource.java   |  37 +-
 .../org/apache/sis/gui/dataset/WindowHandler.java  |  27 +-
 .../org/apache/sis/gui/dataset/package-info.java   |   2 +-
 .../apache/sis/gui/internal/AlignedTableCell.java  |  87 +++
 .../apache/sis/gui/internal/BackgroundThreads.java |   8 +-
 .../apache/sis/gui/internal/DataStoreOpener.java   |  57 +-
 .../apache/sis/gui/internal/ExceptionReporter.java |  36 +-
 .../org/apache/sis/gui/internal/GUIUtilities.java  |  16 -
 .../org/apache/sis/gui/internal/LogHandler.java    |   2 +-
 .../org/apache/sis/gui/internal/Resources.java     |  20 +
 .../apache/sis/gui/internal/Resources.properties   |   4 +
 .../sis/gui/internal/Resources_fr.properties       |   4 +
 .../apache/sis/gui/internal/ShapeConverter.java    | 153 +++++
 .../main/org/apache/sis/gui/internal/Styles.java   |   6 +
 .../apache/sis/gui/internal/io/FileAccessView.java |   4 +-
 .../org/apache/sis/gui/map/GestureFollower.java    |  18 +-
 .../main/org/apache/sis/gui/map/MapCanvas.java     |  43 +-
 .../main/org/apache/sis/gui/map/MapCanvasAWT.java  |  14 +-
 .../main/org/apache/sis/gui/map/MapMenu.java       |  39 +-
 .../main/org/apache/sis/gui/map/StatusBar.java     | 165 ++++--
 .../main/org/apache/sis/gui/map/package-info.java  |   2 +-
 .../apache/sis/gui/map/style/ItemController.java   |  89 +++
 .../apache/sis/gui/map/style/MapContextView.java   | 143 +++++
 .../main/org/apache/sis/gui/map/style/MapItem.java |  26 +-
 .../TreeViewType.java => map/style/MapLayer.java}  |  24 +-
 .../{referencing => map/style}/package-info.java   |  10 +-
 .../sis/gui/metadata/IdentificationInfo.java       |   2 +-
 .../apache/sis/gui/metadata/MetadataSummary.java   |   8 +-
 .../org/apache/sis/gui/referencing/MenuSync.java   |  57 +-
 .../gui/referencing/RecentReferenceSystems.java    | 103 ++--
 .../apache/sis/gui/referencing/package-info.java   |   2 +-
 .../sis/gui/controls/ValueColorMapperApp.java      |   7 +-
 .../main/org/apache/sis/storage/gdal/GDAL.java     | 147 +----
 .../apache/sis/storage/gdal/GDALStoreProvider.java | 126 +++-
 .../org/apache/sis/storage/gdal/TiledCoverage.java |  12 +-
 .../org/apache/sis/storage/gdal/TiledResource.java |  33 +-
 .../org/apache/sis/storage/gdal/package-info.java  |   2 +-
 .../apache/sis/storage/panama/LibraryLoader.java   | 192 ++++---
 .../sis/storage/panama/LibraryReference.java       | 207 +++++++
 .../apache/sis/storage/panama/LibraryStatus.java   |  51 +-
 .../apache/sis/storage/panama/NativeFunctions.java |  91 +--
 .../org/apache/sis/storage/gdal/GDALStoreTest.java |   3 +-
 297 files changed, 17296 insertions(+), 3767 deletions(-)
 create mode 100644 endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/math/FilteringFunction.java
 copy {optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama => endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/internal}/Resources.java (53%)
 copy endorsed/src/{org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3 => org.apache.sis.portrayal/main/org/apache/sis/map/internal}/Resources.properties (56%)
 copy {optional/src/org.apache.sis.gui/main/org/apache/sis/gui => endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map}/internal/Resources_en.java (96%)
 copy {optional/src/org.apache.sis.gui/main/org/apache/sis/gui => endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map}/internal/Resources_fr.java (96%)
 copy endorsed/src/{org.apache.sis.cloud.aws/main/org/apache/sis/cloud/aws/s3/Resources.properties => org.apache.sis.portrayal/main/org/apache/sis/map/internal/Resources_fr.properties} (56%)
 copy {optional/src/org.apache.sis.gui/main/org/apache/sis/gui => endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map}/internal/package-info.java (93%)
 delete mode 100644 endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/MultiResolutionImage.java
 create mode 100644 endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/ReaderTest.java
 create mode 100644 endorsed/src/org.apache.sis.storage.geotiff/test/org/apache/sis/storage/geotiff/untiled.tiff
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImagePyramid.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/ImageTileMatrix.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/IterationDomain.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileReadEvent.java
 rename endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/{base => tiling}/TiledDeferredImage.java (85%)
 rename endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/{base => tiling}/TiledGridCoverage.java (75%)
 rename endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/{base/TiledGridResource.java => tiling/TiledGridCoverageResource.java} (57%)
 create mode 100644 endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/WritableDerivedList.java
 copy endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/{DerivedSetTest.java => DerivedListTest.java} (57%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{parametriccurvesurfaces => }/BilinearGrid.java (92%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{parametriccurvesurfaces => }/Cone.java (93%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{parametriccurvesurfaces => }/Cylinder.java (92%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{parametriccurvesurfaces => }/ParametricCurveSurface.java (97%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{rhumb => }/Rhumb.java (97%)
 delete mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/conicsurfaces/Cone.java
 delete mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/conicsurfaces/Cylinder.java
 delete mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/conicsurfaces/Sphere.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractAffine.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractMatrix.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractSimilarity.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Affine.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Affine1D.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Affine2D.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Affine3D.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Affine4D.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AffineND.java
 copy incubator/src/org.apache.sis.geometry/{test/org/apache/sis/geometries/math/ArrayNbTest.java => main/org/apache/sis/geometries/math/Affines.java} (66%)
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/ArrayFactory.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/ArrayFactoryFFM.java
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/{ArrayMemory.java => ArrayFactoryJava.java} (83%)
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/MatrixND.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/ReadOnly.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Similarity.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Similarity3D.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/SimilarityND.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/SimplifiedTransform.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Transform.java
 copy incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/{CursorUnmodifiable.java => Transform1D.java} (51%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/simplify/TextureAtlas.java (99%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/simplify/greedyinsert/Edge.java (97%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/simplify/greedyinsert/TINBuilder.java (99%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/simplify/greedyinsert/TinDistance.java (96%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/simplify/greedyinsert/WTriangle.java (98%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/triangulate/EarClipping.java (96%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/triangulate/delaunay/Delaunay.java (99%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/triangulate/delaunay/OrientedEdge.java (99%)
 rename incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{ => operation}/triangulate/delaunay/OrientedTriangle.java (99%)
 delete mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/parametriccurvesurfaces/Sphere.java
 copy incubator/src/{org.apache.sis.portrayal.map/main/org/apache/sis/map/SEPresentation.java => org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Animation.java} (52%)
 copy incubator/src/{org.apache.sis.portrayal.map/main/org/apache/sis/map/SEPresentation.java => org.apache.sis.geometry/main/org/apache/sis/geometries/scene/AnimationSampler.java} (52%)
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Camera.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Material.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Model.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/MorphTarget.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Sampler.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/SceneNode.java
 copy incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/{math/AbstractArray.java => scene/Skin.java} (51%)
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
 create mode 100644 incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Texture.java
 copy {buildSrc/src/main/java/org/apache/sis/buildtools/doclet => incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene}/package-info.java (72%)
 rename incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/{ => operation}/simplify/TextureAtlasTest.java (98%)
 rename incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/{ => operation}/triangulate/delaunay/DelaunayTest.java (99%)
 rename incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/{ => operation}/triangulate/delaunay/OrientedEdgeTest.java (98%)
 rename optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/{IsolineRenderer.java => IsolineController.java} (86%)
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/StyleController.java
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/AlignedTableCell.java
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/ShapeConverter.java
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/style/ItemController.java
 create mode 100644 optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/style/MapContextView.java
 copy endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK17.java => optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/style/MapItem.java (55%)
 copy optional/src/org.apache.sis.gui/main/org/apache/sis/gui/{dataset/TreeViewType.java => map/style/MapLayer.java} (57%)
 copy optional/src/org.apache.sis.gui/main/org/apache/sis/gui/{referencing => map/style}/package-info.java (83%)
 create mode 100644 optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryReference.java


(sis) 01/01: Merge branch 'geoapi-4.0' into geoapi-3.1. Contains (non-exhaustive list):

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 76ac26bca233fd47b797ce44f4418b35c62bc849
Merge: 8c45b25f06 3a021d2345
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Mar 31 16:08:05 2026 +0200

    Merge branch 'geoapi-4.0' into geoapi-3.1.
    Contains (non-exhaustive list):
    
    - Implementation of `TileMatrixSet` by the GeoTIFF reader.
    - Redesign of the controls over coverage rendering in JavaFX.
    - Work in the geometry package (incubator).
    - Bug fixes.

 .../sis/coverage/grid/ClippedGridCoverage.java     |   3 +-
 .../org/apache/sis/coverage/grid/GridCoverage.java |  12 +-
 .../apache/sis/coverage/grid/GridCoverage2D.java   |   3 +-
 .../sis/coverage/grid/GridCoverageBuilder.java     |  53 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |   2 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   |  61 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |  24 +-
 .../main/org/apache/sis/feature/FeatureFormat.java |   8 +-
 .../feature/internal/shared/MovingFeatures.java    |  28 +-
 .../org/apache/sis/filter/ComparisonFilter.java    | 141 ++++-
 .../main/org/apache/sis/filter/LogicalFilter.java  |  15 +-
 .../main/org/apache/sis/filter/Optimization.java   |   2 +-
 .../sis/filter/base/BinaryFunctionWidening.java    |   3 +-
 .../apache/sis/filter/math/FilteringFunction.java  |  62 ++
 .../main/org/apache/sis/filter/math/Predicate.java |  28 +-
 .../main/org/apache/sis/image/BandedIterator.java  |  23 +
 .../main/org/apache/sis/image/ComputedImage.java   |  20 +-
 .../main/org/apache/sis/image/ComputedTiles.java   |  26 +-
 .../main/org/apache/sis/image/ImageProcessor.java  |   4 +-
 .../main/org/apache/sis/image/PlanarImage.java     |   2 +-
 .../apache/sis/image/WritablePixelIterator.java    |  50 +-
 .../sis/image/internal/shared/ReshapedImage.java   | 128 ++++-
 .../main/org/apache/sis/image/package-info.java    |   2 +-
 .../sis/coverage/grid/ClippedGridCoverageTest.java |   1 +
 .../apache/sis/coverage/grid/GridExtentTest.java   |  10 +-
 .../apache/sis/filter/ComparisonFilterTest.java    |  98 ++--
 .../apache/sis/filter/DynamicOptimizationTest.java |  19 +
 .../image/internal/shared/ReshapedImageTest.java   |  15 +-
 .../iso/extent/NotSpatioTemporalException.java     |   4 +-
 .../metadata/sql/internal/shared/ScriptRunner.java |   2 +-
 .../org.apache.sis.portrayal/main/module-info.java |   2 +-
 .../coverage/MultiResolutionCoverageLoader.java    |  46 +-
 .../org/apache/sis/map/coverage/RenderingData.java |  53 +-
 .../org/apache/sis/map/internal/Resources.java     | 102 ++++
 .../apache/sis/map/internal/Resources.properties   |  23 +
 .../org/apache/sis/map/internal/Resources_en.java  |  14 +-
 .../org/apache/sis/map/internal/Resources_fr.java  |  14 +-
 .../sis/map/internal/Resources_fr.properties       |  28 +
 .../org/apache/sis/map/internal}/package-info.java |  11 +-
 .../main/org/apache/sis/portrayal/Observable.java  |   2 -
 .../org/apache/sis/portrayal/PlanarCanvas.java     |   7 +-
 .../MultiResolutionCoverageLoaderTest.java         |  18 +-
 .../main/org/apache/sis/geometry/Shapes2D.java     |   2 +-
 .../main/org/apache/sis/referencing/CommonCRS.java |   8 +-
 .../referencing/internal/shared/WKTUtilities.java  |   4 +-
 .../operation/CoordinateOperationContext.java      |  31 +-
 .../operation/CoordinateOperationFinder.java       |  30 +-
 .../operation/CoordinateOperationRegistry.java     |  63 +-
 .../DefaultCoordinateOperationFactory.java         |  58 +-
 .../referencing/operation/SubOperationInfo.java    |   8 +-
 .../sis/referencing/operation/matrix/Matrices.java |   4 +-
 .../sis/referencing/operation/package-info.java    |   2 +-
 .../operation/transform/PassThroughTransform.java  |   2 +-
 .../main/module-info.java                          |   2 +-
 .../sis/storage/geotiff/CompressedSubset.java      |  18 +-
 .../org/apache/sis/storage/geotiff/DataCube.java   |  65 +--
 .../org/apache/sis/storage/geotiff/DataSubset.java |  36 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |   2 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    | 218 +++++--
 .../sis/storage/geotiff/MultiResolutionImage.java  | 286 ---------
 .../org/apache/sis/storage/geotiff/Reader.java     |  22 +-
 .../apache/sis/storage/geotiff/package-info.java   |   2 +-
 .../sis/storage/geotiff/GeoTiffStoreTest.java      |  56 +-
 .../org/apache/sis/storage/geotiff/ReaderTest.java | 124 ++++
 .../org/apache/sis/storage/geotiff/WriterTest.java |   5 +-
 .../org/apache/sis/storage/geotiff/untiled.tiff    | Bin 0 -> 2284 bytes
 .../apache/sis/storage/netcdf/base/FeatureSet.java |  62 +-
 .../sis/storage/netcdf/base/RasterResource.java    |   2 +
 .../org/apache/sis/io/stream/ChannelDataInput.java |   2 +-
 .../sis/storage/AbstractGridCoverageResource.java  |  82 ++-
 .../org/apache/sis/storage/CoverageSubset.java     |  11 +-
 .../main/org/apache/sis/storage/DataStore.java     |  18 +-
 .../apache/sis/storage/GridCoverageResource.java   |  41 +-
 .../main/org/apache/sis/storage/Resource.java      |   4 +-
 .../org/apache/sis/storage/StorageConnector.java   |  25 +-
 .../sis/storage/UnsupportedQueryException.java     |   1 +
 .../aggregate/BandAggregateGridResource.java       |   4 +-
 .../aggregate/ConcatenatedGridResource.java        |  12 +-
 .../apache/sis/storage/aggregate/GridSlice.java    |  12 +-
 .../sis/storage/aggregate/GridSliceLocator.java    |   5 +-
 .../sis/storage/base/GridResourceWrapper.java      |   6 +-
 .../main/org/apache/sis/storage/csv/Store.java     |  13 +-
 .../org/apache/sis/storage/event/StoreEvent.java   |   2 +-
 .../apache/sis/storage/event/StoreListeners.java   |  14 +-
 .../org/apache/sis/storage/event/package-info.java |   4 +-
 .../apache/sis/storage/image/SingleImageStore.java |   6 +-
 .../storage/image/WritableSingleImageStore.java    |   4 +-
 .../org/apache/sis/storage/internal/Resources.java |   5 +
 .../sis/storage/internal/Resources.properties      |   1 +
 .../sis/storage/internal/Resources_fr.properties   |   1 +
 .../apache/sis/storage/tiling/ImagePyramid.java    | 472 +++++++++++++++
 .../apache/sis/storage/tiling/ImageTileMatrix.java | 532 +++++++++++++++++
 .../apache/sis/storage/tiling/IterationDomain.java | 221 +++++++
 .../main/org/apache/sis/storage/tiling/Tile.java   |   4 +-
 .../org/apache/sis/storage/tiling/TileMatrix.java  |  11 +-
 .../apache/sis/storage/tiling/TileMatrixSet.java   |  12 +-
 .../sis/storage/tiling/TileMatrixSetFormat.java    | 524 +++++++++++++++++
 .../apache/sis/storage/tiling/TileReadEvent.java   | 234 ++++++++
 .../org/apache/sis/storage/tiling/TileStatus.java  |   2 +-
 .../{base => tiling}/TiledDeferredImage.java       |  21 +-
 .../{base => tiling}/TiledGridCoverage.java        | 500 ++++++++++------
 .../TiledGridCoverageResource.java}                | 599 +++++++++++++++++--
 .../apache/sis/storage/tiling/TiledResource.java   |   4 +-
 .../apache/sis/storage/tiling/package-info.java    |  10 +-
 .../org/apache/sis/storage/CoverageQueryTest.java  |   8 +-
 .../storage/MemoryGridCoverageResourceTest.java    |   6 +-
 .../sis/storage/test/CoverageReadConsistency.java  |   2 +-
 .../main/org/apache/sis/io/TableAppender.java      |  16 +-
 .../main/org/apache/sis/io/TabularFormat.java      |   4 +-
 .../main/org/apache/sis/io/package-info.java       |   2 +-
 .../main/org/apache/sis/math/DecimalFunctions.java |  29 +-
 .../main/org/apache/sis/math/NumberType.java       |   2 +-
 .../main/org/apache/sis/math/Vector.java           |   2 +-
 .../main/org/apache/sis/util/ArgumentChecks.java   |  26 +-
 .../main/org/apache/sis/util/collection/Cache.java |   4 +-
 .../org/apache/sis/util/collection/Containers.java |  30 +-
 .../apache/sis/util/collection/DerivedList.java    |  31 +-
 .../sis/util/collection/WeakValueHashMap.java      |   6 +-
 .../sis/util/collection/WritableDerivedList.java   | 143 +++++
 .../sis/util/internal/shared/AbstractMap.java      |   2 +-
 .../apache/sis/util/internal/shared/Numerics.java  | 118 +++-
 .../org/apache/sis/util/resources/Vocabulary.java  |  20 +
 .../sis/util/resources/Vocabulary.properties       |   4 +
 .../sis/util/resources/Vocabulary_fr.properties    |   4 +
 .../org/apache/sis/math/DecimalFunctionsTest.java  |  32 +-
 .../{DerivedSetTest.java => DerivedListTest.java}  |  66 +--
 .../apache/sis/util/collection/DerivedMapTest.java |   1 +
 .../apache/sis/util/collection/DerivedSetTest.java |   1 +
 .../BilinearGrid.java                              |   3 +-
 .../{parametriccurvesurfaces => }/Cone.java        |   4 +-
 .../{parametriccurvesurfaces => }/Cylinder.java    |   4 +-
 .../main/org/apache/sis/geometries/Geometries.java |  24 +-
 .../ParametricCurveSurface.java                    |   2 +-
 .../apache/sis/geometries/{rhumb => }/Rhumb.java   |   2 +-
 .../main/org/apache/sis/geometries/Sphere.java     |  66 ++-
 .../apache/sis/geometries/math/AbstractAffine.java | 163 ++++++
 .../apache/sis/geometries/math/AbstractArray.java  |  21 +-
 .../apache/sis/geometries/math/AbstractCursor.java |   2 +-
 .../apache/sis/geometries/math/AbstractMatrix.java | 636 +++++++++++++++++++++
 .../sis/geometries/math/AbstractSimilarity.java    | 329 +++++++++++
 .../apache/sis/geometries/math/AbstractTuple.java  |   4 +-
 .../org/apache/sis/geometries/math/Affine.java     | 122 ++++
 .../org/apache/sis/geometries/math/Affine1D.java   | 161 ++++++
 .../org/apache/sis/geometries/math/Affine2D.java   | 226 ++++++++
 .../org/apache/sis/geometries/math/Affine3D.java   | 365 ++++++++++++
 .../org/apache/sis/geometries/math/Affine4D.java   | 482 ++++++++++++++++
 .../org/apache/sis/geometries/math/AffineND.java   |  99 ++++
 .../org/apache/sis/geometries/math/Affines.java}   |  22 +-
 .../main/org/apache/sis/geometries/math/Array.java |  30 +-
 .../sis/geometries/math/ArrayConcatenated.java     |  11 +-
 .../apache/sis/geometries/math/ArrayFactory.java   | 278 +++++++++
 .../sis/geometries/math/ArrayFactoryFFM.java       | 489 ++++++++++++++++
 .../{ArrayMemory.java => ArrayFactoryJava.java}    | 428 ++++----------
 .../sis/geometries/math/ArraySpliterator.java      |   6 +-
 .../sis/geometries/math/ArrayUnmodifiable.java     |  11 +-
 .../org/apache/sis/geometries/math/Cursor.java     |   2 +-
 .../sis/geometries/math/CursorUnmodifiable.java    |   8 +-
 .../main/org/apache/sis/geometries/math/Maths.java |  32 +-
 .../org/apache/sis/geometries/math/Matrices.java   | 338 +----------
 .../org/apache/sis/geometries/math/Matrix.java     | 137 ++++-
 .../org/apache/sis/geometries/math/Matrix2D.java   | 214 ++++++-
 .../org/apache/sis/geometries/math/Matrix3D.java   | 471 ++++++++++++++-
 .../org/apache/sis/geometries/math/Matrix4D.java   | 470 +++++++++++++--
 .../org/apache/sis/geometries/math/MatrixND.java   | 477 ++++++++++++++++
 .../org/apache/sis/geometries/math/NDArray.java    |  15 +-
 .../org/apache/sis/geometries/math/NDArrays.java   |  83 +--
 .../org/apache/sis/geometries/math/Quaternion.java |  53 +-
 .../apache/sis/geometries/math/Quaternions.java    |   2 +-
 .../org/apache/sis/geometries/math/ReadOnly.java   | 592 +++++++++++++++++++
 .../org/apache/sis/geometries/math/Similarity.java | 200 +++++++
 .../apache/sis/geometries/math/Similarity3D.java   | 197 +++++++
 .../apache/sis/geometries/math/SimilarityND.java   | 195 +++++++
 .../sis/geometries/math/SimplifiedTransform.java   | 106 ++++
 .../org/apache/sis/geometries/math/Transform.java  | 134 +++++
 .../{CursorUnmodifiable.java => Transform1D.java}  |  54 +-
 .../main/org/apache/sis/geometries/math/Tuple.java | 237 +-------
 .../sis/geometries/math/TupleUnmodifiable.java     |  24 +-
 .../org/apache/sis/geometries/math/Vector.java     |  93 +--
 .../org/apache/sis/geometries/math/Vector1D.java   |  26 +-
 .../org/apache/sis/geometries/math/Vector2D.java   |  26 +-
 .../org/apache/sis/geometries/math/Vector3D.java   |  31 +-
 .../org/apache/sis/geometries/math/Vector4D.java   |  42 +-
 .../org/apache/sis/geometries/math/VectorND.java   |  63 +-
 .../org/apache/sis/geometries/math/Vectors.java    |  30 +-
 .../apache/sis/geometries/math/package-info.java   |  20 +-
 .../apache/sis/geometries/mesh/MeshPrimitive.java  |  14 +-
 .../geometries/operation/GeometryOperations.java   |  10 +-
 .../{ => operation}/simplify/TextureAtlas.java     |   2 +-
 .../simplify/greedyinsert/Edge.java                |   2 +-
 .../simplify/greedyinsert/TINBuilder.java          |   2 +-
 .../simplify/greedyinsert/TinDistance.java         |   2 +-
 .../simplify/greedyinsert/WTriangle.java           |   8 +-
 .../{ => operation}/triangulate/EarClipping.java   |  18 +-
 .../triangulate/delaunay/Delaunay.java             |   2 +-
 .../triangulate/delaunay/OrientedEdge.java         |   2 +-
 .../triangulate/delaunay/OrientedTriangle.java     |   2 +-
 .../geometries/parametriccurvesurfaces/Sphere.java |  30 -
 .../processor/spatialedition/ToPrimitive.java      |   2 +-
 .../AbstractArray.java => scene/Animation.java}    |  67 +--
 .../AnimationSampler.java}                         |  63 +-
 .../org/apache/sis/geometries/scene/Camera.java    | 242 ++++++++
 .../org/apache/sis/geometries/scene/Material.java  | 627 ++++++++++++++++++++
 .../org/apache/sis/geometries/scene/Model.java     | 216 +++++++
 .../apache/sis/geometries/scene/MorphTarget.java   | 110 ++++
 .../org/apache/sis/geometries/scene/Sampler.java   | 172 ++++++
 .../org/apache/sis/geometries/scene/SceneNode.java | 510 +++++++++++++++++
 .../{math/AbstractArray.java => scene/Skin.java}   |  73 ++-
 .../org/apache/sis/geometries/scene/Surface.java   | 117 ++++
 .../org/apache/sis/geometries/scene/Texture.java   | 142 +++++
 .../apache/sis/geometries/scene}/package-info.java |  12 +-
 .../geometries/splinesurfaces/BSplineSurface.java  |   2 +-
 .../apache/sis/geometries/math/ArrayNbTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNdTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNfTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNiTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNlTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNsTest.java    |   2 +-
 .../apache/sis/geometries/math/ArrayNubTest.java   |   2 +-
 .../apache/sis/geometries/math/ArrayNuiTest.java   |   2 +-
 .../apache/sis/geometries/math/ArrayNusTest.java   |   2 +-
 .../apache/sis/geometries/math/NDArraysTest.java   |   4 +-
 .../apache/sis/geometries/math/QuaternionTest.java |  35 +-
 .../{ => operation}/simplify/TextureAtlasTest.java |   2 +-
 .../triangulate/delaunay/DelaunayTest.java         |   2 +-
 .../triangulate/delaunay/OrientedEdgeTest.java     |   2 +-
 .../main/org/apache/sis/map/MapItem.java           |   8 +-
 .../apache/sis/storage/geoheif/FromImageIO.java    |   9 +-
 .../main/org/apache/sis/storage/geoheif/Image.java |   3 +-
 .../apache/sis/storage/geoheif/ImageResource.java  |  34 +-
 .../src/org.apache.sis.gui/main/module-info.java   |   2 +-
 .../main/org/apache/sis/gui/Widget.java            |   8 +-
 .../apache/sis/gui/controls/FormatApplicator.java  |   6 +-
 .../apache/sis/gui/controls/SyncWindowList.java    |   6 +-
 .../apache/sis/gui/controls/ValueColorMapper.java  |  12 +-
 .../apache/sis/gui/coverage/BandRangeTable.java    |   8 +-
 .../apache/sis/gui/coverage/CoverageCanvas.java    | 335 +++++++++--
 .../apache/sis/gui/coverage/CoverageControls.java  | 155 +++--
 .../apache/sis/gui/coverage/CoverageExplorer.java  |  36 +-
 .../apache/sis/gui/coverage/CoverageStyling.java   |  16 +-
 .../apache/sis/gui/coverage/GridSliceSelector.java |  12 +-
 .../sis/gui/coverage/ImagePropertyExplorer.java    |   6 +-
 ...IsolineRenderer.java => IsolineController.java} |  82 ++-
 .../apache/sis/gui/coverage/StyleController.java   | 173 ++++++
 .../sis/gui/coverage/StyledRenderingData.java      |   6 +-
 .../apache/sis/gui/coverage/TileMatrixSetPane.java | 499 ++++++++++++++++
 .../apache/sis/gui/coverage/ViewAndControls.java   |  22 +-
 .../org/apache/sis/gui/coverage/package-info.java  |   2 +-
 .../main/org/apache/sis/gui/dataset/LogViewer.java |   5 +-
 .../org/apache/sis/gui/dataset/ResourceCell.java   | 138 +++--
 .../apache/sis/gui/dataset/ResourceExplorer.java   |  52 +-
 .../org/apache/sis/gui/dataset/ResourceItem.java   | 178 ++++--
 .../org/apache/sis/gui/dataset/ResourceTree.java   |  50 +-
 .../org/apache/sis/gui/dataset/RootResource.java   |  37 +-
 .../org/apache/sis/gui/dataset/WindowHandler.java  |  27 +-
 .../org/apache/sis/gui/dataset/package-info.java   |   2 +-
 .../apache/sis/gui/internal/AlignedTableCell.java  |  87 +++
 .../apache/sis/gui/internal/BackgroundThreads.java |   8 +-
 .../apache/sis/gui/internal/DataStoreOpener.java   |  57 +-
 .../apache/sis/gui/internal/ExceptionReporter.java |  36 +-
 .../org/apache/sis/gui/internal/GUIUtilities.java  |  16 -
 .../org/apache/sis/gui/internal/LogHandler.java    |   2 +-
 .../org/apache/sis/gui/internal/Resources.java     |  20 +
 .../apache/sis/gui/internal/Resources.properties   |   4 +
 .../sis/gui/internal/Resources_fr.properties       |   4 +
 .../apache/sis/gui/internal/ShapeConverter.java    | 153 +++++
 .../main/org/apache/sis/gui/internal/Styles.java   |   6 +
 .../apache/sis/gui/internal/io/FileAccessView.java |   4 +-
 .../org/apache/sis/gui/map/GestureFollower.java    |  18 +-
 .../main/org/apache/sis/gui/map/MapCanvas.java     |  43 +-
 .../main/org/apache/sis/gui/map/MapCanvasAWT.java  |  14 +-
 .../main/org/apache/sis/gui/map/MapMenu.java       |  39 +-
 .../main/org/apache/sis/gui/map/StatusBar.java     | 165 ++++--
 .../main/org/apache/sis/gui/map/package-info.java  |   2 +-
 .../apache/sis/gui/map/style/ItemController.java   |  89 +++
 .../apache/sis/gui/map/style/MapContextView.java   | 143 +++++
 .../main/org/apache/sis/gui/map/style/MapItem.java |  35 +-
 .../org/apache/sis/gui/map/style/MapLayer.java     |  37 +-
 .../org/apache/sis/gui/map/style/package-info.java |  14 +-
 .../sis/gui/metadata/IdentificationInfo.java       |   2 +-
 .../apache/sis/gui/metadata/MetadataSummary.java   |   8 +-
 .../org/apache/sis/gui/referencing/MenuSync.java   |  57 +-
 .../gui/referencing/RecentReferenceSystems.java    | 103 ++--
 .../apache/sis/gui/referencing/package-info.java   |   2 +-
 .../sis/gui/controls/ValueColorMapperApp.java      |   7 +-
 .../main/org/apache/sis/storage/gdal/GDAL.java     | 147 +----
 .../apache/sis/storage/gdal/GDALStoreProvider.java | 126 +++-
 .../org/apache/sis/storage/gdal/TiledCoverage.java |  12 +-
 .../org/apache/sis/storage/gdal/TiledResource.java |  33 +-
 .../org/apache/sis/storage/gdal/package-info.java  |   2 +-
 .../apache/sis/storage/panama/LibraryLoader.java   | 192 ++++---
 .../sis/storage/panama/LibraryReference.java       | 207 +++++++
 .../apache/sis/storage/panama/LibraryStatus.java   |  51 +-
 .../apache/sis/storage/panama/NativeFunctions.java |  91 +--
 .../org/apache/sis/storage/gdal/GDALStoreTest.java |   3 +-
 294 files changed, 17472 insertions(+), 3629 deletions(-)

diff --cc endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TileMatrixSetFormat.java
index 0000000000,a132628bb7..abfcbcd9d2
mode 000000,100644..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
@@@ -1,0 -1,521 +1,524 @@@
+ /*
+  * 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.storage.tiling;
+ 
+ import java.io.PrintWriter;
+ import java.io.StringWriter;
+ import java.io.IOException;
+ import java.io.UncheckedIOException;
+ import java.text.Format;
+ import java.util.Locale;
+ import java.util.List;
+ import java.util.ArrayList;
+ import java.util.Map;
+ import java.util.HashMap;
+ import java.util.TimeZone;
+ import java.util.Objects;
+ import java.util.Optional;
+ import java.util.Arrays;
+ import java.util.StringJoiner;
+ import java.text.NumberFormat;
+ import java.text.ParseException;
+ import java.text.ParsePosition;
+ import org.opengis.util.GenericName;
+ import org.opengis.referencing.crs.CoordinateReferenceSystem;
+ import org.opengis.referencing.operation.TransformException;
+ import org.opengis.metadata.extent.GeographicBoundingBox;
+ import org.apache.sis.util.ArraysExt;
+ import org.apache.sis.util.CharSequences;
+ import org.apache.sis.util.logging.Logging;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.resources.Vocabulary;
+ 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.referencing.IdentifiedObjects;
+ import org.apache.sis.coverage.grid.GridExtent;
+ import org.apache.sis.coverage.grid.IncompleteGridGeometryException;
+ import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
+ import org.apache.sis.io.CompoundFormat;
+ 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.
+  *
+  * <h2>Limitations</h2>
+  * <ul>
+  *   <li>The current implementation can only format tile matrices — parsing is supported.</li>
+  *   <li>{@code TileMatrixSetFormat}, like most {@code java.text.Format} subclasses, is not thread-safe.</li>
+  * </ul>
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @version 1.7
+  * @since   1.7
+  */
+ public class TileMatrixSetFormat extends CompoundFormat<TileMatrixSet> {
+     /**
+      * For cross-version compatibility.
+      */
+     private static final long serialVersionUID = 2612127094991996016L;
+ 
+     /**
+      * Helper class for string representation of an image pyramid as a table.
+      * Each instance describes one table row for one {@link ImageTileMatrix}.
+      */
+     private static final class Row {
+         /** The tile matrix identifier. */
+         final String identifier;
+ 
+         /** The tile matrix resolution in each <abbr>CRS</abbr> dimensions. */
+         final double[] resolution;
+ 
+         /** The string representations of the tile matrix resolution. */
+         final String[] formattedResolution;
+ 
+         /** The number of tiles in each grid dimension. */
+         final String[] tileCount;
+ 
+         /** The tile sizes in pixels. */
+         final String[] tileSize;
+ 
+         /** The extent of the tiling scheme. */
+         private final GridExtent tilingScheme;
+ 
+         /**
+          * Creates one row in the table for the given matrix.
+          *
+          * @param  matrix         the matrix for which to store information.
+          * @param  integerFormat  a number format configured for integer values.
+          * @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) {
+             final GenericName id = matrix.getIdentifier();
+             identifier = (id != null) ? id.toString() : "";
+             resolution = matrix.getResolution();
+             formattedResolution = new String[resolution.length];
+             tilingScheme = matrix.getTilingScheme().getExtent();
+             tileCount = new String[tilingScheme.getDimension()];
+             for (int i=0; i<tileCount.length; i++) {
+                 tileCount[i] = integerFormat.format(tilingScheme.getSize(i));
+             }
+             final int[] ts = ImageTileMatrix.getTileSize(matrix);
+             tileSize = new String[ts != null ? ts.length : 0];
+             for (int i=0; i<tileSize.length; i++) {
+                 tileSize[i] = integerFormat.format(ts[i]);
+             }
+         }
+ 
+         /**
+          * Updates the axis name in the dimension <var>i</var> of the grid extent.
+          * This method verifies that grid dimensions in all rows have the same axis names.
+          */
+         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));
++                String name = axis.identifier();
++                if (name == null) {
++                    name = axis.name().toLowerCase(Locale.US);
++                }
+                 final String current = gridAxes[i];
+                 if (current == null) {
+                     gridAxes[i] = name;
+                 } else if (!current.equals(name)) {
+                     gridAxes[i] = "";
+                 }
+             });
+         }
+ 
+         /**
+          * Creates the string representation of the resolutions in all resolution columns of all rows.
+          * This method computes the number of fraction digits based on the resolution values of all rows.
+          *
+          * @param  rows    the rows in which to format the resolutions.
+          * @param  format  the number formats to use. Its number of fraction digits will be updated.
+          * @return the maximal number of resolution values found in all rows.
+          *         This value should be equal to the number of dimensions in the <abbr>CRS</abbr>.
+          */
+         static int formatResolutions(final List<Row> rows, final NumberFormat format) {
+             final var values = new double[rows.size()];
+             for (int i=0; ; i++) {
+                 int count = 0;
+                 for (final Row row : rows) {
+                     if (i < row.resolution.length) {
+                         values[count++] = row.resolution[i];
+                     }
+                 }
+                 if (count == 0) return i;
+                 final int n = Numerics.suggestFractionDigits(ArraysExt.resize(values, count));
+                 format.setMinimumFractionDigits(n);
+                 format.setMaximumFractionDigits(n);
+                 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];
+                     }
+                 }
+             }
+         }
+     }
+ 
+     /**
+      * The error that occurred while formatting a Tile Matrix Set.
+      */
+     private transient Throwable error;
+ 
+     /**
+      * Creates a new formatter using the given locale and timezone.
+      *
+      * @param  locale    the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
+      * @param  timezone  the timezone, or {@code null} for UTC.
+      */
+     public TileMatrixSetFormat(final Locale locale, final TimeZone timezone) {
+         super(locale, timezone);
+     }
+ 
+     /**
+      * Returns the type of values formatted by this {@code Format} instance.
+      *
+      * @return the type of values formatted by this {@code Format} instance.
+      */
+     @Override
+     public final Class<TileMatrixSet> getValueType() {
+         return TileMatrixSet.class;
+     }
+ 
+     /**
+      * Formats the properties of the given Tile Matrix Set for presentation before the main table.
+      * The properties are formatted as {@link String}s using the locale given at construction time.
+      * The returned map contains the following entries if the corresponding properties were found:
+      *
+      * <table class="sis">
+      *   <caption>Tile Matrix Set (<abbr>TMS</abbr>) formatted properties</caption>
+      *   <tr><th>Key</th>                  <th>Value type</th>                           <th>Description</th></tr>
+      *   <tr><td>{@code "identifier"}</td> <td>{@link String}</td>                       <td>Identifier of the <abbr>TMS</abbr>.</td></tr>
+      *   <tr><td>{@code "referencing"}</td><td>{@link String}</td>                       <td>Name of the <abbr>CRS</abbr>, or reason why not available.</td></tr>
+      *   <tr><td>{@code "crs"}</td>        <td>{@link CoordinateReferenceSystem}</td>    <td>The <abbr>CRS</abbr>.</td></tr>
+      *   <tr><td>{@code "bbox"}</td>       <td>{@link DefaultGeographicBoundingBox}</td> <td>Bounding box of the <abbr>TMS</abbr>.</td></tr>
+      * </table>
+      *
+      * <p>If the {@code "crs"} property is non-null, then the {@code "referencing"} property is the <abbr>CRS</abbr> name.
+      * Conversely, if the {@code "crs"} property is null, then the {@code "referencing"} property is a message saying that
+      * the <abbr>CRS</abbr> was not available or the reason why it was not available.</p>
+      *
+      * The returned properties can be completed by a call to {@link #formatTable(Iterable, Map)}.
+      *
+      * @param  matrices  the tile matrices to format.
+      * @return properties of the header of the given tile matrix set.
+      */
+     public Map<String, Object> formatHeader(final TileMatrixSet matrices) {
+         final var addTo = new HashMap<String, Object>();
+         addTo.put("identifier", matrices.getIdentifier());
+         try {
+             try {
+                 final CoordinateReferenceSystem crs = matrices.getCoordinateReferenceSystem();
+                 addTo.put("referencing", IdentifiedObjects.getDisplayName(crs, getLocale()));
+                 addTo.put("crs", crs);
+             } catch (IncompleteGridGeometryException e) {
+                 addTo.put("referencing", e.getLocalizedMessage());
+             }
+             matrices.getEnvelope().ifPresent((envelope) -> {
+                 try {
+                     final var bbox = new DefaultGeographicBoundingBox();
+                     bbox.setBounds(envelope);
+                     bbox.setInclusion(null);
+                     addTo.put("bbox", bbox);
+                 } catch (TransformException e) {
+                     // Ignore because this exception may be normal if the envelope has no spatial component.
+                     Logging.ignorableException(ImageTileMatrix.LOGGER, TileMatrixSetFormat.class, "format", e);
+                 }
+             });
+         } catch (BackingStoreException e) {
+             // The CRS or envelope may be missing in the header, but we may still be able to format the table.
+             addError(e.getCause());
+         }
+         addTo.values().removeIf(Objects::isNull);
+         return addTo;
+     }
+ 
+     /**
+      * Formats the properties of the given Tile Matrices in a way suitable to a tabular format.
+      * The properties are formatted as {@link String}s using the locale given at construction time.
+      * The returned map contains the following entries if the corresponding properties were found:
+      *
+      * <table class="sis">
+      *   <caption>Tile Matrices formatted properties</caption>
+      *   <tr><th>Key</th>                   <th>Value type</th>         <th>Description</th></tr>
+      *   <tr><td>{@code "identifiers"}</td> <td>{@code String[]}</td>   <td>Column of the identifier of each Tile Matrix.</td></tr>
+      *   <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 "gridAxes"}</td>    <td>{@code String[]}</td>   <td>Name of grid axes.</td></tr>
+      * </table>
+      *
+      * The {@code "tileSizes"} property 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.
+      * The length of the {@code "identifiers"} array is that number of rows.
+      * All other arrays have a length equal to the number of columns in a group of columns,
+      * which is 2 in the usual case of two-dimensional Tile Matrix Sets.
+      * The {@code "resolutions[i]"}, {@code "tileCounts[i]"} and {@code "tileSizes[i]"} arrays,
+      * where <var>i</var> is a column index, all have a length equal to the number of rows.
+      * Some element may be {@code null} if the corresponding data could not be extracted.</p>
+      *
+      * @param  matrices  the tile matrices to format.
+      * @param  addTo     where to put the properties of the given tile matrix set.
+      * @return number of rows in the table to format.
+      */
+     public int formatTable(final Iterable<? extends TileMatrix> matrices, final Map<String, Object> addTo) {
+         final var rows = new ArrayList<Row>();
+         int gridDimension = 0, sizeDimension = 0;
+         final var integerFormat = (NumberFormat) getFormat(Long.class);
+         for (final TileMatrix matrix : matrices) try {
+             final var row = new Row(matrix, integerFormat);
+             gridDimension = Math.max(gridDimension, row.tileCount.length);
+             sizeDimension = Math.max(sizeDimension, row.tileSize.length);
+             rows.add(row);  // Add only on success.
+         } catch (RuntimeException e) {
+             addError(e);    // Skip the row. Next row will be tried.
+         }
+         final int crsDimension = Row.formatResolutions(rows, (NumberFormat) getFormat(Double.class));
+         final int numRows     = rows.size();
+         final var identifiers = new String[numRows];
+         final var resolutions = new String[ crsDimension][numRows];
+         final var tileCounts  = new String[gridDimension][numRows];
+         final var tileSizes   = new String[sizeDimension][numRows];
+         final var gridAxes    = new String[gridDimension];
+         for (int j=0; j<numRows; j++) {
+             final Row row = rows.get(j);
+             identifiers[j] = row.identifier;
+             for (int i = Math.min(crsDimension, row.resolution.length); --i >= 0;) {
+                 resolutions[i][j] = row.formattedResolution[i];
+             }
+             for (int i = Math.min(gridDimension, row.tileCount.length); --i >= 0;) {
+                 tileCounts[i][j] = row.tileCount[i];
+                 row.searchCommonAxisName(gridAxes, i);
+             }
+             for (int i = Math.min(sizeDimension, row.tileSize.length); --i >= 0;) {
+                 tileSizes[i][j] = row.tileSize[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);
+         for (int i=0; i<gridAxes.length; i++) {
+             final String name = gridAxes[i];
+             if (name != null && name.isBlank()) {
+                 gridAxes[i] = null;
+             }
+         }
+         if (!ArraysExt.allEquals(gridAxes, null)) {
+             addTo.put("gridAxes", gridAxes);
+         }
+         return numRows;
+     }
+ 
+     /**
+      * Returns localized resources for the table header.
+      */
+     private Vocabulary vocabulary() {
+         return Vocabulary.forLocale(getLocale());
+     }
+ 
+     /**
+      * Formats a textual representation of the given tile matrices.
+      * This method delegates to {@link #format(TileMatrixSet, Appendable)}
+      * with a temporary buffer.
+      *
+      * @param  matrices  the tile matrices to format.
+      * @return a string representation of the given Tile Matrix Set.
+      */
+     public String format(TileMatrixSet matrices) {
+         return format(matrices, false);
+     }
+ 
+     /**
+      * Formats the given tile matrices, optionally with a report of exceptions.
+      *
+      * @param  matrices     the tile matrices to format.
+      * @param  reportError  whether to report exceptions.
+      * @return a string representation of the given Tile Matrix Set.
+      */
+     final String format(final TileMatrixSet matrices, final boolean reportError) {
+         final var buffer = new StringBuilder(1000);
+         try {
+             format(matrices, buffer);
+             if (!reportError || error == null) {
+                 return buffer.toString();
+             }
+             final var writer = new StringWriter(buffer.length()).append(buffer);
+             vocabulary().appendLabel(Vocabulary.Keys.Warnings, writer);
+             error.printStackTrace(new PrintWriter(writer.append(' ')));
+             return writer.append(System.lineSeparator()).toString();
+         } catch (IOException e) {
+             throw new UncheckedIOException(e);
+         }
+     }
+ 
+     /**
+      * Formats a textual representation of the given tile matrices.
+      * First, a header is formatted with the <abbr>TMS</abbr> identifier,
+      * the Coordinate Reference System and the geographic bounding box.
+      * Then, each tile matrix is formatted as a row in a table.
+      *
+      * @param  matrices    the tile matrices to format.
+      * @param  toAppendTo  where to format the object.
+      * @throws IOException if an error occurred while writing to the given appendable.
+      */
+     @Override
+     public void format(final TileMatrixSet matrices, final Appendable toAppendTo) throws IOException {
+         final Vocabulary vocabulary = vocabulary();
+         final Map<String, Object> properties = formatHeader(matrices);
+         final int numRows = formatTable(matrices.getTileMatrices().values(), properties);
+         Object value = properties.get("identifier");
+         if (value != null) {
+             toAppendTo.append(vocabulary.getString(Vocabulary.Keys.TileMatrixSets)).append(' ')
+                       .append(vocabulary.getString(Vocabulary.Keys.Quoted_1, value))
+                       .append(System.lineSeparator());
+         }
+         value = properties.get("referencing");
+         if (value != null) {
+             if (properties.get("crs") != null) {
+                 vocabulary.appendLabel(Vocabulary.Keys.ReferenceSystem, toAppendTo);
+                 toAppendTo.append(' ');
+             }
+             toAppendTo.append(value.toString()).append(System.lineSeparator());
+         }
+         value = properties.get("bbox");
+         if (value != null) {
+             final var bbox = (DefaultGeographicBoundingBox) value;
+             final var mf = (TreeTableFormat) getFormat(GeographicBoundingBox.class);
+             mf.setColumns(TableColumn.NAME, TableColumn.VALUE);
+             toAppendTo.append(mf.format(bbox.asTreeTable()));
+         }
+         /*
+          * The header was formatted by above code. The following code formats the main table.
+          * First, we get the values to format in all columns and prepend the number of spaces
+          * needed for right alignment.
+          */
+         final var identifiers = (String[])   properties.get("identifiers");
+         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};
+         columnGroups = ArraysExt.resize(columnGroups, ArraysExt.removeNulls(columnGroups));
+         for (final String[][] columns : columnGroups) {
+             for (final String[] column : columns) {
+                 Arrays.stream(column).mapToInt(String::length).max().ifPresent((length) -> {
+                     for (int j=0; j<column.length; j++) {
+                         String e  = column[j];
+                         column[j] = CharSequences.spaces(length - e.length()) + e;
+                     }
+                 });
+             }
+         }
+         final var table = new TableAppender(toAppendTo);
+         table.appendHorizontalSeparator();
+         if (identifiers != null) table.append(vocabulary.getString(Vocabulary.Keys.Identifier)).nextColumn();
+         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();
+         table.appendHorizontalSeparator();
+         for (int j=0; j<numRows; j++) {
+             if (identifiers != null) {
+                 table.setCellAlignment(TableAppender.ALIGN_LEFT);
+                 table.append(identifiers[j]).nextColumn();
+                 table.setCellAlignment(TableAppender.ALIGN_RIGHT);
+             }
+             for (final String[][] columns : columnGroups) {
+                 final var joiner = new StringJoiner(" × ");
+                 for (String[] column : columns) {
+                     joiner.add(column[j]);
+                 }
+                 table.append(joiner.toString()).nextColumn();
+             }
+             table.nextLine();
+         }
+         table.appendHorizontalSeparator();
+         table.flush();
+     }
+ 
+     /**
+      * Not supported.
+      *
+      * @return currently never return.
+      * @throws ParseException currently always thrown.
+      * @hidden Not implemented.
+      */
+     @Override
+     public TileMatrixSet parse(CharSequence text, ParsePosition pos) throws ParseException {
+         throw new ParseException(Errors.forLocale(getLocale())
+                 .getString(Errors.Keys.UnsupportedOperation_1, "parse"), pos.getIndex());
+     }
+ 
+     /**
+      * Creates a new format to use for formatting values of the given type.
+      * This method adds the creation of {@link TreeTableFormat}.
+      *
+      * @param  valueType  the base type of values to parse or format.
+      * @return the format to use for parsing of formatting values of the given type, or {@code null} if none.
+      * @hidden the addition compared to parent class are implementation details.
+      */
+     @Override
+     protected Format createFormat(final Class<?> valueType) {
+         if (valueType == GeographicBoundingBox.class) {
+             return new TreeTableFormat(getLocale(), getTimeZone());
+         }
+         return super.createFormat(valueType);
+     }
+ 
+     /**
+      * Records that an error occurred.
+      *
+      * @param  e  the error that occurred.
+      */
+     private void addError(final Throwable e) {
+         if (error == null) {
+             error = e;
+         } else {
+             error.addSuppressed(e);
+         }
+     }
+ 
+     /**
+      * If an error occurred while formatting the Tile Matrix Set, returns that error.
+      *
+      * @return the error that occurred during formatting.
+      */
+     public Optional<Throwable> getError() {
+         return Optional.ofNullable(error);
+     }
+ 
+     /**
+      * Clears the error status. This method should be invoked if the same {@code TileMatrixSetFormat}
+      * instance is used for formatting many {@code TileMatrixSet} instances.
+      */
+     public void clear() {
+         error = null;
+     }
+ }
diff --cc endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
index 5b9a4d65e8,e820ce116b..9569abb254
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
@@@ -55,11 -53,16 +56,13 @@@ import org.opengis.geometry.MismatchedD
  // Specific to the geoapi-3.1 and geoapi-4.0 branches:
  import org.opengis.coverage.CannotEvaluateException;
  
 -// Specific to the geoapi-4.0 branch:
 -import org.opengis.coordinate.MismatchedDimensionException;
 -
  
  /**
-  * Base class of grid coverage read from a resource where data are stored in tiles.
+  * Base class of grid coverages that are read from resources with data stored in tiles.
   * This grid coverage may represent only a subset of the coverage resource.
-  * Tiles are read from the storage only when first needed.
+  * Tiles are read from the storage when first needed, then cached using weak references.
+  * The reading of tiles is done by the {@link #readTiles(TileIterator)} method,
+  * which must be defined by subclasses.
   *
   * <h2>Cell coordinates</h2>
   * When there is no subsampling, this coverage uses the same cell coordinates as the originating resource.
diff --cc endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
index cafa992617,ca28d60e38..c393e45edb
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
@@@ -773,7 -773,31 +773,31 @@@ public final class ArgumentChecks 
          if (indices != null) {
              final int dimension = indices.length;
              if (dimension != expected) {
 -                throw new MismatchedDimensionException(Errors.format(
 +                throw new org.opengis.geometry.MismatchedDimensionException(Errors.format(
+                         Errors.Keys.MismatchedDimension_3, name, expected, dimension));
+             }
+         }
+     }
+ 
+     /**
+      * Ensures that the given array of indices, if non-null, has the expected number of dimensions
+      * (taken as its length). This method does nothing if the given array is null.
+      *
+      * @param  name      the name of the argument to be checked. Used only if an exception is thrown.
+      * @param  expected  the expected number of dimensions.
+      * @param  indices   the array of indices to check for its number of dimensions, or {@code null}.
+      * @throws MismatchedDimensionException if the given array of indices is non-null and does not have
+      *         the expected number of dimensions (taken as its length).
+      *
+      * @since 1.7
+      */
+     public static void ensureDimensionMatches(final String name, final int expected, final long[] indices)
+             throws MismatchedDimensionException
+     {
+         if (indices != null) {
+             final int dimension = indices.length;
+             if (dimension != expected) {
+                 throw new MismatchedDimensionException(Errors.format(
                          Errors.Keys.MismatchedDimension_3, name, expected, dimension));
              }
          }
diff --cc incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
index bceafeae88,4160a45cc5..9b8faafe56
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
@@@ -24,6 -25,10 +25,10 @@@ import org.apache.sis.geometries.math.V
  import org.apache.sis.geometries.math.Vectors;
  import org.apache.sis.geometry.GeneralEnvelope;
  import org.apache.sis.util.ArgumentChecks;
+ import static org.opengis.annotation.Specification.ISO_19107;
+ import org.opengis.annotation.UML;
+ import org.opengis.geometry.DirectPosition;
 -import org.opengis.metadata.Identifier;
++import org.opengis.referencing.ReferenceIdentifier;
  
  
  /**
@@@ -120,4 -127,61 +127,61 @@@ public final class Sphere extends Abstr
          return env;
      }
  
+     // methods from ParametricCurveSurface
+ 
+     @Override
+     public int getRows() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public int getColumns() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public List<DirectPosition> getControlPoints() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public List<DirectPosition> getDataPoints() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public GeometryType getHorizontalCurveType() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public GeometryType getVerticalCurveType() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public List<Knot> getKnots() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public Curve getHorizontalCurve(double v) {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public Curve getVerticalCurve(double u) {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
+     public DirectPosition getSurface(double u, double v) {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
+     @Override
 -    public Identifier getName() {
++    public ReferenceIdentifier getName() {
+         throw new UnsupportedOperationException("Not supported yet.");
+     }
+ 
  }