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 0df8a4ce59617c126bd8f50c36347dd388b92ffa
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat May 2 13:47:34 2026 +0200

    `EngineeringDatum` created by `GridGeometry.createGridCRS(…)` should have 
unique name.
    This is needed for avoiding that SIS thinks that two engineering CRSs are 
convertible
    while actually they are from unrelated grids.
---
 .../apache/sis/coverage/grid/GridCRSBuilder.java   | 28 ++++++++++++----------
 .../org/apache/sis/coverage/grid/GridGeometry.java | 18 +++++++++++---
 .../main/org/apache/sis/referencing/CommonCRS.java | 27 +++++++++++----------
 .../referencing/factory/IdentifiedObjectSet.java   |  2 +-
 .../main/org/apache/sis/storage/DataStore.java     | 10 ++++----
 .../org/apache/sis/util/resources/Vocabulary.java  | 10 ++++++++
 .../sis/util/resources/Vocabulary.properties       |  6 +++--
 .../sis/util/resources/Vocabulary_fr.properties    |  6 +++--
 8 files changed, 68 insertions(+), 39 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCRSBuilder.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCRSBuilder.java
index 8244d295a7..1f96d230e7 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCRSBuilder.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCRSBuilder.java
@@ -38,16 +38,15 @@ import 
org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.DerivedCRS;
 import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.datum.EngineeringDatum;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
-import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.cs.AbstractCS;
 import org.apache.sis.referencing.cs.CoordinateSystems;
@@ -106,14 +105,6 @@ final class GridCRSBuilder extends 
ReferencingFactoryContainer {
      */
     private static final InternationalString SCOPE = 
Resources.formatInternational(Resources.Keys.CrsToGridConversion);
 
-    /**
-     * Name of the coordinate systems created by this class.
-     * The current version uses the same name for all coordinate systems.
-     * We do not create different names for different combination of axes.
-     */
-    private static final NamedIdentifier CS_NAME = new NamedIdentifier(
-            Citations.SIS, 
Vocabulary.formatInternational(Vocabulary.Keys.GridExtent));
-
     /**
      * The extent of the grid geometry, or {@code null} if none.
      */
@@ -207,7 +198,8 @@ final class GridCRSBuilder extends 
ReferencingFactoryContainer {
             dimensionNames = new DimensionNameType[dimension];
         }
         final CoordinateSystem cs = createCS(dimension, dimensionNames, 
directions(dimensionNames), 1, true);
-        return getCRSFactory().createEngineeringCRS(properties(name), 
CommonCRS.Engineering.GRID.datum(), cs);
+        final EngineeringDatum datum = 
getDatumFactory().createEngineeringDatum(properties(name));
+        return 
getCRSFactory().createEngineeringCRS(properties(datum.getName()), datum, cs);
     }
 
     /**
@@ -341,6 +333,15 @@ toGrid: try {
         return "Grid based on " + name;
     }
 
+    /**
+     * Returns the coordinate reference system that we use as a template for 
object names.
+     * This template uses generic terms such as "Cell indices" for the 
<abbr>CRS</abbr> name
+     * and "Unknown grid" for the datum.
+     */
+    private static EngineeringCRS template() {
+        return CommonCRS.Engineering.GRID.crs();
+    }
+
     /**
      * Creates the coordinate system for the derived or engineering 
<abbr>CRS</abbr> of a grid.
      *
@@ -412,7 +413,7 @@ toGrid: try {
          * coordinate system type in last resort.
          */
         @SuppressWarnings("LocalVariableHidesMemberVariable")
-        final Map<String,?> properties = properties(CS_NAME);
+        final Map<String,?> properties = 
properties(template().getCoordinateSystem().getName());
         final CoordinateSystemAxis axis = axes[0];
         switch (dimension) {
             case 1:  {
@@ -533,6 +534,7 @@ toGrid: try {
         if (cs == null) {
             return Optional.empty();
         }
-        return 
Optional.of(getCRSFactory().createEngineeringCRS(properties(cs.getName()), 
CommonCRS.Engineering.GRID.datum(), cs));
+        final EngineeringCRS template = template();
+        return 
Optional.of(getCRSFactory().createEngineeringCRS(properties(template.getName()),
 template.getDatum(), cs));
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
index b1fb40ac4f..d575d101e8 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
@@ -94,6 +94,7 @@ import static org.apache.sis.referencing.CRS.SeparationMode;
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.coordinate.CoordinateMetadata;
 import org.opengis.coordinate.MismatchedDimensionException;
+import org.opengis.referencing.crs.EngineeringCRS;
 
 
 /**
@@ -1891,10 +1892,19 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      * by the {@linkplain #getGridToCRS grid to <abbr>CRS</abbr>} transform,
      * then this method creates {@link DerivedCRS} instances derived from the
      * {@link #getCoordinateReferenceSystem() <abbr>CRS</abbr> of this grid}.
-     * This strategy makes possible to use the returned <abbr>CRS</abbr> in a 
chain of operations
-     * with (for example) {@link org.apache.sis.referencing.CRS#findOperation 
CRS.findOperation(…)}.
+     * This strategy makes possible to use the returned <abbr>CRS</abbr> in a 
chain of coordinate operations
+     * created by (for example) {@link 
org.apache.sis.referencing.CRS#findOperation CRS.findOperation(…)}.
      * Otherwise (if there is no grid to <abbr>CRS</abbr> transform or no 
real-world <abbr>CRS</abbr>),
-     * this method creates {@link org.opengis.referencing.crs.EngineeringCRS} 
instances.
+     * then this method creates an {@link 
org.opengis.referencing.crs.EngineeringCRS} instance
+     * associated to an engineering datum identified by the given {@code name}.
+     *
+     * <h4>Recommendation about the name</h4>
+     * The {@code name} argument is not very important when this method 
creates {@link DerivedCRS} instances,
+     * because the datum is inherited from the real world <abbr>CRS</abbr>. 
However, if this method fallbacks
+     * on {@link EngineeringCRS}, then the {@code name} argument become the 
only way to determine whether
+     * a coordinate operation is possible between two such engineering 
<abbr>CRS</abbr>s.
+     * It is recommended to use an identifier which is unique for the grid. It 
may be, for example, derived
+     * from the {@linkplain 
org.apache.sis.storage.GridCoverageResource#getIdentifier() resource 
identifier}.
      *
      * <p><b>Alternative:</b> if the target grid geometry is known in advance,
      * {@link #createTransformTo(GridGeometry, PixelInCell)} can provide a
@@ -1906,6 +1916,8 @@ public class GridGeometry implements LenientComparable, 
Serializable {
      * @throws InvalidGeodeticParameterException if characteristics of this 
grid geometry disallow this operation.
      * @throws FactoryException if another error occurred during the use of a 
referencing factory.
      *
+     * @see #createTransformTo(GridGeometry, PixelInCell)
+     *
      * @since 1.7
      */
     public CoordinateReferenceSystem createGridCRS(final Identifier name, 
final PixelInCell anchor) throws FactoryException {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 6b09decb55..c72d9fce98 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -51,7 +51,6 @@ import org.opengis.referencing.datum.TemporalDatum;
 import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.datum.EngineeringDatum;
 import org.opengis.metadata.extent.GeographicBoundingBox;
-import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
 import org.apache.sis.referencing.datum.DatumOrEnsemble;
 import org.apache.sis.referencing.datum.DefaultVerticalDatum;
 import org.apache.sis.referencing.datum.DefaultTemporalDatum;
@@ -1915,7 +1914,7 @@ public enum CommonCRS {
      * </table></blockquote>
      *
      * @author  Martin Desruisseaux (Geomatys)
-     * @version 1.1
+     * @version 1.7
      * @since   1.1
      */
     public enum Engineering {
@@ -1967,7 +1966,7 @@ public enum CommonCRS {
          *   <tr><th>Unit:</th> <td>{@link Units#UNITY}</td></tr>
          * </table></blockquote>
          */
-        GRID(new DefaultEngineeringDatum(Map.of(EngineeringDatum.NAME_KEY, 
"Cell indices"))),
+        GRID(new 
DefaultEngineeringDatum(properties(Vocabulary.Keys.UnknownGrid))),
 
         /**
          * A single-dimensional coordinate system for time in seconds since an 
unknown epoch.
@@ -1984,7 +1983,7 @@ public enum CommonCRS {
          *
          * @see Temporal
          */
-        TIME(new DefaultEngineeringDatum(Map.of(EngineeringDatum.NAME_KEY, 
"Time")));
+        TIME(new DefaultEngineeringDatum(properties(Vocabulary.Keys.Time)));
 
         /**
          * The datum.
@@ -2006,20 +2005,20 @@ public enum CommonCRS {
         /**
          * Returns the coordinate reference system associated to this 
engineering object.
          *
-         * @return the CRS associated to this enum.
+         * @return the CRS associated to this enumeration value.
          */
         public synchronized EngineeringCRS crs() {
             if (crs == null) {
                 final String x, y;
                 final AxisDirection dx, dy;
-                final Map<String,Object> pcs = Map.of(CartesianCS.NAME_KEY, 
datum.getName());
-                final Map<String,Object> properties = new HashMap<>(pcs);
                 CoordinateSystem cs = null;
+                Map<String, ?> properties = Map.of(CartesianCS.NAME_KEY, 
datum.getName());
+                Map<String, ?> csName = properties;
                 switch (this) {
                     case GEODISPLAY: {
                         x = "i"; dx = AxisDirection.EAST;
                         y = "j"; dy = AxisDirection.SOUTH;
-                        properties.put(EngineeringCRS.NAME_KEY, new 
NamedIdentifier(Citations.WMS, "1"));
+                        properties = Map.of(EngineeringCRS.NAME_KEY, new 
NamedIdentifier(Citations.WMS, "1"));
                         break;
                     }
                     case DISPLAY: {
@@ -2030,19 +2029,21 @@ public enum CommonCRS {
                     case GRID: {
                         x = "i"; dx = AxisDirection.COLUMN_POSITIVE;
                         y = "j"; dy = AxisDirection.ROW_POSITIVE;
+                        properties = properties(Vocabulary.Keys.CellIndices);
+                        csName = properties;
                         break;
                     }
                     case TIME: {
                         x  = y  = "t";
                         dx = dy = AxisDirection.FUTURE;
-                        cs = new DefaultTimeCS(pcs, new 
DefaultCoordinateSystemAxis(
-                                Map.of(TimeCS.NAME_KEY, x), x, dx, 
Units.SECOND));
+                        cs = new DefaultTimeCS(properties,
+                                new 
DefaultCoordinateSystemAxis(Map.of(TimeCS.NAME_KEY, x), x, dx, Units.SECOND));
                         break;
                     }
                     default: throw new AssertionError(this);
                 }
                 if (cs == null) {
-                    cs = new DefaultCartesianCS(pcs,
+                    cs = new DefaultCartesianCS(csName,
                             new 
DefaultCoordinateSystemAxis(Map.of(CartesianCS.NAME_KEY, x), x, dx, 
Units.PIXEL),
                             new 
DefaultCoordinateSystemAxis(Map.of(CartesianCS.NAME_KEY, y), y, dy, 
Units.PIXEL));
                 }
@@ -2054,7 +2055,7 @@ public enum CommonCRS {
         /**
          * Returns the datum associated to this engineering object.
          *
-         * @return the datum associated to this enum.
+         * @return the datum associated to this enumeration value.
          */
         public EngineeringDatum datum() {
             return datum;
@@ -2101,7 +2102,7 @@ public enum CommonCRS {
      * Puts the given name in a map of properties to be given to object 
constructors.
      */
     private static Map<String,?> properties(final InternationalString name) {
-        return Map.of(NAME_KEY, new NamedIdentifier(null, name));
+        return Map.of(IdentifiedObject.NAME_KEY, new NamedIdentifier(null, 
name));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
index c3c4f5c59f..58280eeb33 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
@@ -317,7 +317,7 @@ public class IdentifiedObjectSet<T extends 
IdentifiedObject> extends AbstractSet
      * Returns {@code true} if this collection contains the specified {@code 
IdentifiedObject}.
      *
      * @param  object  the {@code IdentifiedObject} to test for presence in 
this set.
-     * @return {@code true} if the given object is presents in this set.
+     * @return {@code true} if the given object is present in this set.
      * @throws ClassCastException if the given object is non-null and not an 
instance of {@code <T>}.
      */
     @Override
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
index 5317bc2658..c0ab806cbb 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
@@ -289,12 +289,12 @@ public abstract class DataStore implements Resource, 
Localized, AutoCloseable {
      *     findResource(getIdentifier().toString()) == this
      *     }
      *
-     * Note that this identifier is not guaranteed to be unique between 
different {@code DataStore} instances;
-     * it only needs to be unique among the resources provided by this data 
store instance.
+     * Note that this identifier is not guaranteed to be unique between 
different {@code DataStore} instances.
+     * It only needs to be unique among the resources provided by this data 
store instance.
      *
      * <h4>Default implementation</h4>
-     * <p>The default implementation searches for an identifier in the 
metadata,
-     * at the location shown below, provided that conditions are met:</p>
+     * The default implementation searches for an identifier in the metadata,
+     * at the locations shown below, provided that the following conditions 
are met:
      *
      * <blockquote>
      * <p><b>Path:</b> {@link Resource#getMetadata() metadata} /
@@ -302,7 +302,7 @@ public abstract class DataStore implements Resource, 
Localized, AutoCloseable {
      * {@link 
org.apache.sis.metadata.iso.identification.AbstractIdentification#getCitation() 
citation} /
      * {@link 
org.apache.sis.metadata.iso.citation.DefaultCitation#getIdentifiers() 
identifier}</p>
      *
-     * <p><b>Condition:</b> in default implementation, the identifier is 
presents only if exactly one
+     * <p><b>Condition:</b> in default implementation, the identifier is 
present only if exactly one
      * {@code citation} is found at above path. If two or more {@code 
citation} instances are found,
      * the identification is considered ambiguous and an empty value is 
returned.</p>
      *
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java
index 9fea4b3345..5400228dde 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.java
@@ -179,6 +179,11 @@ public class Vocabulary extends IndexedResourceBundle {
          */
         public static final short CellGeometry = 23;
 
+        /**
+         * Cell indices
+         */
+        public static final short CellIndices = 286;
+
         /**
          * Cells
          */
@@ -1359,6 +1364,11 @@ public class Vocabulary extends IndexedResourceBundle {
          */
         public static final short Units = 206;
 
+        /**
+         * Unknown grid
+         */
+        public static final short UnknownGrid = 287;
+
         /**
          * Unnamed
          */
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.properties
index b7e9cbf0e0..28348fe187 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary.properties
@@ -40,6 +40,7 @@ CausedBy_1              = Caused by {0}
 Cells                   = Cells
 CellCount_1             = {0} cells
 CellGeometry            = Cell geometry
+CellIndices             = Cell indices
 CharacterEncoding       = Character encoding
 Characteristics         = Characteristics
 Class                   = Class
@@ -275,12 +276,13 @@ True                    = True
 Type                    = Type
 TypeOfResource          = Type of resource
 Units                   = Units
+UnavailableContent      = Unavailable content.
+UnknownGrid             = Unknown grid
 Unnamed                 = Unnamed
 Unnamed_1               = Unnamed #{0}
 Unspecified             = Unspecified
-Untitled                = Untitled
-UnavailableContent      = Unavailable content.
 UnspecifiedDatumChange  = Unspecified datum change
+Untitled                = Untitled
 UpperBound              = Upper bound
 UserHome                = User home directory
 Value                   = Value
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary_fr.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary_fr.properties
index 98b196c92d..d72a1e502d 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary_fr.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Vocabulary_fr.properties
@@ -47,6 +47,7 @@ CausedBy_1              = Caus\u00e9e par {0}
 Cells                   = Cellules
 CellCount_1             = {0} cellules
 CellGeometry            = G\u00e9om\u00e9trie des cellules
+CellIndices             = Indices des cellules
 CharacterEncoding       = Encodage des caract\u00e8res
 Characteristics         = Caract\u00e9ristiques
 Class                   = Classe
@@ -282,12 +283,13 @@ True                    = Vrai
 Type                    = Type
 TypeOfResource          = Type de ressource
 Units                   = Unit\u00e9s
+UnavailableContent      = Contenu non-disponible.
+UnknownGrid             = Grille inconnue
 Unnamed                 = Sans nom
 Unnamed_1               = Sans nom \u2116{0}
 Unspecified             = Non-sp\u00e9cifi\u00e9
-Untitled                = Sans titre
-UnavailableContent      = Contenu non-disponible.
 UnspecifiedDatumChange  = Changement de r\u00e9f\u00e9rentiel non 
sp\u00e9cifi\u00e9
+Untitled                = Sans titre
 UpperBound              = Limite haute
 UserHome                = R\u00e9pertoire de l\u2019utilisateur
 Value                   = Valeur

Reply via email to