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 280e84ecf9bc6046c60c9a5c02dbf1c4af20aff9
Merge: 5b57d58d6b c221ff093a
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Sep 27 22:41:33 2025 +0200

    Merge branch 'geoapi-4.0' into geoapi-3.1

 .../sis/parameter/DefaultParameterDescriptor.java  |  14 +-
 ...ensorValues.java => MatrixParameterValues.java} |  54 +-
 .../org/apache/sis/parameter/MatrixParameters.java | 979 +++++++++++++++++++--
 .../sis/parameter/MatrixParametersAlphaNum.java    | 125 ---
 .../org/apache/sis/parameter/TensorParameters.java | 796 +----------------
 .../main/org/apache/sis/parameter/Verifier.java    |  86 +-
 .../referencing/factory/sql/AuthorityCodes.java    |  13 +-
 .../referencing/factory/sql/EPSGDataAccess.java    | 646 ++++++++++----
 .../sis/referencing/factory/sql/EPSGFactory.java   |  12 +
 .../referencing/internal/EPSGParameterDomain.java  |  53 --
 .../internal/ParameterizedTransformBuilder.java    |   7 +-
 .../referencing/internal/SignReversalComment.java  |  10 +
 .../operation/MathTransformContext.java            |   4 +-
 .../sis/referencing/operation/matrix/Matrices.java |   2 +-
 .../operation/provider/AbstractProvider.java       |  21 +
 .../sis/referencing/operation/provider/Affine.java | 155 ++--
 .../referencing/operation/provider/EPSGName.java   |  31 +-
 .../operation/provider/FormulaCategory.java        |  51 ++
 .../sis/parameter/DefaultParameterValueTest.java   |  35 +-
 ...uesTest.java => MatrixParameterValuesTest.java} | 188 ++--
 .../parameter/MatrixParametersAlphaNumTest.java    |  66 +-
 .../sis/parameter/MatrixParametersEPSGTest.java    | 101 +++
 .../apache/sis/parameter/MatrixParametersTest.java | 253 +++++-
 .../apache/sis/parameter/TensorParametersTest.java | 300 -------
 .../sis/referencing/crs/DefaultDerivedCRSTest.java |   2 +
 .../referencing/factory/sql/EPSGFactoryTest.java   |  43 +
 .../operation/projection/EquirectangularTest.java  |   8 +-
 .../referencing/operation/provider/AffineTest.java |  25 +-
 .../operation/provider/LongitudeRotationTest.java  |   6 +-
 .../transform/EllipsoidToRadiusTransformTest.java  |   6 +-
 .../InterpolatedGeocentricTransformTest.java       |  16 +-
 .../transform/SpecializableTransformTest.java      |   6 +
 .../report/CoordinateOperationMethods.java         | 198 ++---
 .../report/CoordinateReferenceSystems.java         | 705 +++++++--------
 .../sis/referencing/report/HTMLGenerator.java      |  24 +-
 .../resources/embedded/EmbeddedResourcesTest.java  |  29 +-
 .../factory/sql/epsg/DataScriptUpdater.java        |  10 +
 37 files changed, 2695 insertions(+), 2385 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
index e20873df88,3aec5d7e68..43ab947d75
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ParameterizedTransformBuilder.java
@@@ -668,8 -668,7 +668,8 @@@ public class ParameterizedTransformBuil
              if (provider instanceof AbstractProvider) {
                  provider = ((AbstractProvider) 
provider).variantFor(transform);
              }
 +            // A call to `unique` needs to be last because it sets 
`factory.lastMethod` as a side-effect.
-             return unique(swapAndScaleAxes(unique(transform)));
+             return unique(swapAndScaleAxes(transform));
          } catch (FactoryException exception) {
              if (warning != null) {
                  exception.addSuppressed(warning);
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateOperationMethods.java
index 7db6885447,205d55d710..d8d1f48ec4
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateOperationMethods.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateOperationMethods.java
@@@ -297,6 -273,18 +273,18 @@@ public class CoordinateOperationMethod
          closeTags(table);
      }
  
+     /**
+      * Returns {@code true} if at least one non-deprecated parameter has a 
remark.
+      */
+     private static boolean hasRemarks(final ParameterDescriptorGroup group) {
+         for (final GeneralParameterDescriptor gp : group.descriptors()) {
 -            if (!isDeprecated(gp) && ((ParameterDescriptor<?>) 
gp).getRemarks().isPresent()) {
++            if (!isDeprecated(gp) && ((ParameterDescriptor<?>) 
gp).getRemarks() != null) {
+                 return true;
+             }
+         }
+         return false;
+     }
+ 
      /**
       * Writes the table of parameters.
       * Table columns will be:
@@@ -361,6 -333,27 +333,27 @@@
                  println("td class=\"sep center\" colspan=\"3\"", domain);
              }
              println("td class=\"sep\"", escape(getDefaultValue(param, 
getUnit(param))));
+             if (hasRemarks) {
 -                String remarks = 
toLocalizedString(param.getRemarks().orElse(null));
++                String remarks = toLocalizedString(param.getRemarks());
+                 if (remarks != null) {
+                     Integer index = footnotes.putIfAbsent(remarks, 
footnotes.size() + 1);
+                     if (index == null) {
+                         index = footnotes.size();
+                     }
+                     if (param.getMinimumOccurs() == 0) {
+                         remarks = "Optional ";
+                     } else {
+                         final Comparable<?> min = param.getMinimumValue();
+                         if ((min instanceof Number n) && n.doubleValue() == 
((Number) param.getMaximumValue()).doubleValue()) {
+                             remarks = "Unmodifiable ";
+                         } else {
+                             remarks = "See note ";
+                         }
+                     }
+                     remarks += toSuperScript(index);
+                 }
+                 println("td class=\"sep\"", escape(remarks));
+             }
          }
          closeTags(table);
          if (!footnotes.isEmpty()) {
diff --cc 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
index 7ac4e9064b,23b2c3c33d..aee3037235
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
@@@ -647,34 -437,99 +437,99 @@@ public final class CoordinateReferenceS
          }
  
          /**
-          * Computes the {@link #reducedName} field value.
+          * Invoked when the <abbr>CRS</abbr> cannot be constructed because of 
the given error.
+          *
+          * @param  factory  the factory which created the <abbr>CRS</abbr>.
+          * @param  cause    the reason why the <abbr>CRS</abbr> cannot be 
constructed.
+          * @param  code     the authority code without <abbr>HTML</abbr> 
escapes.
+          * @return whether to ignore this row.
           */
-         final void setup(final Datum datum, final Set<String> 
unusedDatumMapping) {
-             final String datumName;
-             if (datum != null) {
-                 datumName = datum.getName().getCode();
+         final boolean setValues(final CRSAuthorityFactory factory, final 
FactoryException cause, final String code) {
+             if (code.startsWith(Constants.PROJ4 + 
DefaultNameSpace.DEFAULT_SEPARATOR)) {
+                 return true;
+             }
+             String message = cause.getMessage();
+             if (message == null) {
+                 message = cause.toString();
+             }
+             remark = escape(message).toString();
+             hasError = true;
+             try {
+                 name = 
toLocalizedString(factory.getDescriptionText(CoordinateReferenceSystem.class, 
code).get());
+             } catch (FactoryException e) {
+                 Logging.unexpectedException(null, 
CoordinateReferenceSystems.class, "createRow", e);
+             }
+             if (code.startsWith("AUTO2:")) {
+                 // It is normal to be unable to instantiate an "AUTO" CRS,
+                 // because those authority codes need parameters.
+                 hasError = false;
+                 remark = "Projected";
+                 setSection(CommonCRS.WGS84.datum(true));
              } else {
-                 // Temporary patch (TODO: remove after we implemented the 
missing methods in SIS)
-                 if (name.startsWith("NSIDC EASE-Grid")) {
-                     datumName = "Unspecified datum";
-                 } else if (code.equals("EPSG:2163")) {
-                     datumName = "Unspecified datum";
-                 } else if (code.equals("EPSG:5818")) {
-                     datumName = "Seismic bin grid datum";
+                 if (cause instanceof NoSuchIdentifierException e) {
+                     remark = '“' + e.getIdentifierCode() + "” operation 
method is not yet supported.";
                  } else {
-                     datumName = null;       // Keep ordering based on the 
name.
+                     remark = cause.getLocalizedMessage();
                  }
+                 setSection(null);
              }
-             if (datumName != null) {
-                 final String prefix;
-                 final Map.Entry<String,String> group = 
SECTION_TITLES.floorEntry(datumName);
-                 if (group != null && datumName.startsWith(prefix = 
group.getKey())) {
-                     unusedDatumMapping.remove(prefix);
-                     section = group.getValue();
-                 } else {
-                     section = datumName;
+             return false;
+         }
+ 
+         /**
+          * Invoked when a <abbr>CRS</abbr> has been successfully created.
+          *
+          * @param  factory  the factory which created the <abbr>CRS</abbr>.
+          * @param  crs      the object created from the authority code.
+          * @return the created row, or {@code null} if the row should be 
ignored.
+          */
+         final void setValues(final CRSAuthorityFactory factory, 
CoordinateReferenceSystem crs) {
+             name = escape(crs.getName().getCode()).toString();
+             final CoordinateReferenceSystem crsXY = 
AbstractCRS.castOrCopy(crs).forConvention(AxesConvention.RIGHT_HANDED);
+             if (!Utilities.deepEquals(crs.getCoordinateSystem(), 
crsXY.getCoordinateSystem(), ComparisonMode.IGNORE_METADATA)) {
+                 annotation = YX_ORDER;
+             }
+             remark = getRemark(crs);
+             /*
+              * If the object is deprecated, find the replacement.
+              * We do not take the whole comment because it may be pretty long.
+              */
+             if (crs instanceof Deprecable dep) {
+                 isDeprecated = dep.isDeprecated();
+                 if (isDeprecated) {
+                     String replacedBy = null;
 -                    InternationalString i18n = crs.getRemarks().orElse(null);
++                    InternationalString i18n = crs.getRemarks();
+                     for (final Identifier id : crs.getIdentifiers()) {
+                         if (id instanceof Deprecable did && 
did.isDeprecated()) {
 -                            i18n = did.getRemarks().orElse(null);
++                            i18n = did.getRemarks();
+                             if (id instanceof DeprecatedCode dc) {
+                                 replacedBy = dc.replacedBy;
+                             }
+                             break;
+                         }
+                     }
+                     remark = toLocalizedString(i18n);
+                     /*
+                      * If a replacement exists for a deprecated CRS, use the 
datum of the replacement instead of
+                      * the datum of the deprecated CRS for determining in 
which section to put the CRS. The reason
+                      * is that some CRS are deprecated because they were 
associated to the wrong datum, in which
+                      * case the deprecated CRS would appear in the wrong 
section if we do not apply this correction.
+                      */
+                     if (replacedBy != null) try {
+                         crs = factory.createCoordinateReferenceSystem("EPSG:" 
+ replacedBy);
+                     } catch (FactoryException e) {
+                         // Ignore - keep the datum of the deprecated object.
+                     }
                  }
              }
+             setSection(CRS.getSingleComponents(crs).get(0).getDatum());
+         }
+ 
+         /**
+          * Computes the {@link #reducedName} field value.
+          * It determines the section where the <abbr>CRS</abbr> will be 
placed.
+          */
+         private void setSection(final Datum datum) {
              /*
               * Get a copy of the name in all lower case.
               */

Reply via email to