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. */
