This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/sis.git
commit 23f2e78a1acf9d898c9b8a44be3698e0c939d2bb Merge: f975967824 a1e3ecb82c Author: Martin Desruisseaux <[email protected]> AuthorDate: Fri Sep 5 14:54:35 2025 +0200 Merge branch 'geoapi-3.1'. NOTICE | 2 +- README.md | 2 +- .../apache/sis/console/MetadataCommandTest.java | 3 +- .../iso/extent/DefaultGeographicDescription.java | 2 +- .../sis/openoffice/ReferencingFunctions.java | 7 +- .../sis/referencing/AbstractIdentifiedObject.java | 13 +- .../sis/referencing/StandardDefinitions.java | 21 +- .../sis/referencing/cs/CoordinateSystems.java | 3 + .../sis/referencing/datum/DatumOrEnsemble.java | 17 +- .../referencing/datum/DefaultGeodeticDatum.java | 2 + .../referencing/factory/GeodeticObjectFactory.java | 5 +- .../internal/PositionalAccuracyConstant.java | 11 - .../apache/sis/referencing/internal/Resources.java | 10 +- .../sis/referencing/internal/Resources.properties | 2 +- .../referencing/internal/Resources_fr.properties | 2 +- .../apache/sis/referencing/operation/CRSPair.java | 2 +- .../operation/CoordinateOperationFinder.java | 244 +++++++++++++++------ .../operation/CoordinateOperationRegistry.java | 108 +++++---- .../sis/referencing/operation/matrix/Matrix1.java | 17 +- .../sis/referencing/operation/matrix/Matrix2.java | 16 +- .../CoordinateSystemTransformBuilder.java | 3 +- .../org/apache/sis/referencing/CommonCRSTest.java | 24 +- .../operation/CoordinateOperationFinderTest.java | 10 +- .../DefaultCoordinateOperationFactoryTest.java | 2 +- .../sis/test/integration/ConsistencyTest.java | 1 - .../apache/sis/setup/OptionalInstallations.java | 4 +- .../org/apache/sis/util/resources/Vocabulary.java | 15 +- .../sis/util/resources/Vocabulary.properties | 3 +- .../sis/util/resources/Vocabulary_fr.properties | 3 +- netbeans-project/ivy-settings.xml | 2 +- optional/build.gradle.kts | 3 + optional/src/org.apache.sis.gui/bundle/README | 8 +- .../sis/referencing/factory/sql/epsg/README.md | 4 +- parent/pom.xml | 2 +- settings.gradle.kts | 4 +- 35 files changed, 373 insertions(+), 204 deletions(-) diff --cc endorsed/src/org.apache.sis.openoffice/main/org/apache/sis/openoffice/ReferencingFunctions.java index c6a2624b8e,f94b1178b6..88ca0e81a1 --- a/endorsed/src/org.apache.sis.openoffice/main/org/apache/sis/openoffice/ReferencingFunctions.java +++ b/endorsed/src/org.apache.sis.openoffice/main/org/apache/sis/openoffice/ReferencingFunctions.java @@@ -42,9 -42,8 +42,10 @@@ import org.apache.sis.storage.DataStore import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.base.CodeType; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.referencing.ObjectDomain; +// Specific to the main branch: +import org.apache.sis.referencing.DefaultObjectDomain; ++import org.apache.sis.referencing.datum.DefaultDatumEnsemble; +import org.apache.sis.referencing.internal.Legacy; /** @@@ -306,8 -306,8 +307,10 @@@ public class ReferencingFunctions exten } else if (object instanceof CoordinateSystem) { cs = (CoordinateSystem) object; } else { -- final Class<?> actual; -- if (object instanceof AbstractIdentifiedObject) { ++ final Object actual; ++ if (object instanceof DefaultDatumEnsemble) { ++ actual = "DatumEnsemble"; ++ } else if (object instanceof AbstractIdentifiedObject) { actual = ((AbstractIdentifiedObject) object).getInterface(); } else { actual = Classes.getClass(object); diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java index 27dc8e2409,15739e97e9..985c33a045 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java @@@ -76,11 -76,11 +76,13 @@@ import static org.apache.sis.util.privy // Specific to the main and geoapi-3.1 branches: import org.opengis.referencing.ReferenceIdentifier; + import org.opengis.referencing.operation.Conversion; + import org.opengis.referencing.operation.Projection; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.referencing.ObjectDomain; +// Specific to the main branch: +import org.opengis.referencing.ReferenceSystem; +import org.apache.sis.metadata.iso.DefaultIdentifier; +import org.apache.sis.referencing.internal.Legacy; /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java index fc062eace9,5ce8ea62fc..a67a8e3916 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/StandardDefinitions.java @@@ -376,12 -376,23 +376,23 @@@ final class StandardDefinitions static VerticalDatum createVerticalDatum(final short code) { final String name; final String alias; - final RealizationMethod method; ++ final VerticalDatumType method; switch (code) { - case 5100: name = "Mean Sea Level"; alias = "MSL"; break; - case 5103: name = "North American Vertical Datum 1988"; alias = "NAVD88"; break; - default: throw new AssertionError(code); + case 5100: { + name = "Mean Sea Level"; + alias = "MSL"; - method = RealizationMethod.TIDAL; ++ method = VerticalDatumType.DEPTH; // Actually `RealizationMethod.TIDAL` + break; + } + case 5103: { + name = "North American Vertical Datum 1988"; + alias = "NAVD88"; - method = RealizationMethod.LEVELLING; ++ method = VerticalDatumType.GEOIDAL; // Actually `RealizationMethod.LEVELLING`; + break; + } + default: throw new AssertionError(code); } - return new DefaultVerticalDatum(properties(code, name, alias, true), VerticalDatumType.GEOIDAL); + return new DefaultVerticalDatum(properties(code, name, alias, true), method); } /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java index 5243d12f90,89ab1e4124..c527fac71b --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DatumOrEnsemble.java @@@ -315,11 -325,12 +315,12 @@@ public final class DatumOrEnsemble exte if (sourceDatum != null && Utilities.equalsIgnoreMetadata(sourceDatum, targetDatum)) { return Optional.of(targetDatum); } - DatumEnsemble<D> sourceEnsemble; - DatumEnsemble<D> targetEnsemble; - DatumEnsemble<D> selected; - if ((isMember(selected = targetEnsemble = (DatumEnsemble<D>) targetCRS.getDatumEnsemble(), sourceDatum)) || - (isMember(selected = sourceEnsemble = (DatumEnsemble<D>) sourceCRS.getDatumEnsemble(), targetDatum)) || + DefaultDatumEnsemble<D> sourceEnsemble; + DefaultDatumEnsemble<D> targetEnsemble; + DefaultDatumEnsemble<D> selected; + if ((isMember(selected = targetEnsemble = (DefaultDatumEnsemble<D>) getDatumEnsemble(targetCRS), sourceDatum)) || - (isMember(selected = sourceEnsemble = (DefaultDatumEnsemble<D>) getDatumEnsemble(sourceCRS), targetDatum))) ++ (isMember(selected = sourceEnsemble = (DefaultDatumEnsemble<D>) getDatumEnsemble(sourceCRS), targetDatum)) || + (sourceEnsemble != null && sourceEnsemble == targetEnsemble)) // Optimization for a common case. { return Optional.of(constructor.apply(selected)); } @@@ -361,8 -372,8 +362,8 @@@ * @param ensemble the ensemble to test, or {@code null}. * @return whether the ensemble contains the given datum. */ - private static boolean isMember(final DatumEnsemble<?> ensemble, final IdentifiedObject datum) { + private static boolean isMember(final DefaultDatumEnsemble<?> ensemble, final IdentifiedObject datum) { - if (ensemble != null) { + if (ensemble != null && datum != null) { for (final Datum member : ensemble.getMembers()) { if (Utilities.equalsIgnoreMetadata(datum, member)) { return true; diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java index c647333610,245afd1036..040dd2259e --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticObjectFactory.java @@@ -1380,14 -1435,14 +1380,13 @@@ public class GeodeticObjectFactory exte } /** - * Creates a parametric <abbr>CRS</abbr> with a datum that may be a datum ensemble. - * If the given {@code datum} argument is a {@linkplain DefaultDatumEnsemble datum ensemble - * viewed as a pseudo-datum}, then it is used as the {@code ensemble} argument of the above - * constructor. + * Creates a parametric <abbr>CRS</abbr> from a datum. + * This is a shortcut for the {@linkplain #createParametricCRS(Map, ParametricDatum, DefaultDatumEnsemble, ParametricCS) + * more generic method} without datum ensemble. * * @param properties name and other properties to give to the new object. - * Available properties are {@linkplain ObjectFactory listed there}. - * @param datum temporal datum to use in created CRS. - * @param cs the temporal coordinate system for the created CRS. + * @param datum the parametric datum or datum ensemble viewed as a pseudo-datum. + * @param cs the parametric coordinate system for the created <abbr>CRS</abbr>. * @return the coordinate reference system for the given properties. * @throws FactoryException if the object creation failed. */ diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java index 611d3b2e35,8378f742fb..3aa4b827fe --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java @@@ -527,12 -531,9 +527,9 @@@ public class CoordinateOperationFinder * Coordinate system change (including change in the number of dimensions) without datum shift. * May contain the addition of ellipsoidal height or spherical radius, which need an ellipsoid. */ - final boolean isGeographic = (sourceCS instanceof EllipsoidalCS); - identifier = isGeographic != (targetCS instanceof EllipsoidalCS) ? GEOCENTRIC_CONVERSION : AXIS_CHANGES; - final var builder = factorySIS.getMathTransformFactory().builder(Constants.COORDINATE_SYSTEM_CONVERSION); + final var builder = CoordinateOperations.builder(factorySIS.getMathTransformFactory(), Constants.COORDINATE_SYSTEM_CONVERSION); - final var ellipsoid = (isGeographic ? sourceDatum : targetDatum).getEllipsoid(); - builder.setSourceAxes(sourceCS, ellipsoid); - builder.setTargetAxes(targetCS, ellipsoid); + builder.setSourceAxes(sourceCS, sourceDatum.getEllipsoid()); + builder.setTargetAxes(targetCS, targetDatum.getEllipsoid()); transform = builder.create(); method = builder.getMethod(); parameters = builder.parameters(); diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformBuilder.java index 225b068543,b102444f2f..77e7477225 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformBuilder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransformBuilder.java @@@ -43,11 -43,9 +43,12 @@@ import org.apache.sis.referencing.opera import org.apache.sis.referencing.operation.provider.GeocentricToGeographic; import org.apache.sis.referencing.operation.provider.GeographicToGeocentric; import org.apache.sis.referencing.privy.WKTUtilities; + import org.apache.sis.util.Utilities; import org.apache.sis.util.resources.Errors; +// Specific to the main branch: +import org.apache.sis.referencing.privy.CoordinateOperations; + /** * Builder of transforms between coordinate systems. diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java index 3ffc248bff,bdfcb1cf3f..0257d6f35f --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java @@@ -45,7 -45,7 +45,6 @@@ import static org.apache.sis.util.privy // Test dependencies import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; --import org.opengis.test.Validators; import static org.apache.sis.test.Assertions.assertEqualsIgnoreMetadata; import static org.apache.sis.test.Assertions.assertMessageContains; import static org.apache.sis.test.TestUtilities.*; @@@ -130,7 -130,7 +129,6 @@@ public final class CommonCRSTest extend @Test public void testGeographic() { final GeographicCRS geographic = CommonCRS.WGS84.geographic(); -- Validators.validate(geographic); GeodeticObjectVerifier.assertIsWGS84(geographic, true, true); assertSame(geographic, CommonCRS.WGS84.geographic(), "Cached value"); } @@@ -142,7 -142,7 +140,6 @@@ public void testNormalizedGeographic() { final GeographicCRS geographic = CommonCRS.WGS84.geographic(); final GeographicCRS normalized = CommonCRS.WGS84.normalizedGeographic(); -- Validators.validate(normalized); assertSame(geographic.getDatum(), normalized.getDatum()); /* * Compare axes. Note that axes in different order have different EPSG codes. @@@ -160,7 -160,7 +157,6 @@@ @Test public void testGeographic3D() { final GeographicCRS crs = CommonCRS.WGS72.geographic3D(); -- Validators.validate(crs); assertEquals ("WGS 72", crs.getName().getCode()); assertSame (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum()); assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum()); @@@ -179,7 -179,7 +175,6 @@@ @Test public void testGeocentric() { final GeodeticCRS crs = CommonCRS.WGS72.geocentric(); -- Validators.validate(crs); assertEquals ("WGS 72", crs.getName().getCode()); assertSame (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum()); assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum()); @@@ -198,7 -198,7 +193,6 @@@ @Test public void testSpherical() { final GeodeticCRS crs = CommonCRS.ETRS89.spherical(); -- Validators.validate(crs); assertEquals ("ETRS89", crs.getName().getCode()); assertSame (CommonCRS.ETRS89.geographic().getDatum(), crs.getDatum()); assertNotSame(CommonCRS.WGS84 .datum(true), crs.getDatum()); @@@ -215,34 -215,37 +209,29 @@@ * Verifies the vertical datum enumeration. */ @Test - @SuppressWarnings("deprecation") public void testVertical() { for (final CommonCRS.Vertical e : CommonCRS.Vertical.values()) { - final RealizationMethod method; + final VerticalDatumType method; final String axisName, datumName; switch (e) { - case NAVD88: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 1988"; method = VerticalDatumType. GEOIDAL; break; - case NAVD88: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 1988"; method = RealizationMethod. GEOID; break; - case BAROMETRIC: axisName = "Barometric altitude"; datumName = "Constant pressure surface"; method = RealizationMethod.valueOf("BAROMETRIC"); break; - case MEAN_SEA_LEVEL: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level"; method = RealizationMethod. TIDAL; break; - case DEPTH: axisName = AxisNames.DEPTH; datumName = "Mean Sea Level"; method = RealizationMethod. TIDAL; break; ++ case NAVD88: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 1988"; method = null; break; + case BAROMETRIC: axisName = "Barometric altitude"; datumName = "Constant pressure surface"; method = VerticalDatumType. BAROMETRIC; break; - case MEAN_SEA_LEVEL: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level"; method = VerticalDatumType. GEOIDAL; break; - case DEPTH: axisName = AxisNames.DEPTH; datumName = "Mean Sea Level"; method = VerticalDatumType. GEOIDAL; break; ++ case MEAN_SEA_LEVEL: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level"; method = VerticalDatumType. DEPTH; break; ++ case DEPTH: axisName = AxisNames.DEPTH; datumName = "Mean Sea Level"; method = VerticalDatumType. DEPTH; break; case ELLIPSOIDAL: axisName = AxisNames.ELLIPSOIDAL_HEIGHT; datumName = "Ellipsoid"; method = VerticalDatumTypes.ellipsoidal(); break; - case OTHER_SURFACE: axisName = "Height"; datumName = "Other surface"; method = null; break; + case OTHER_SURFACE: axisName = "Height"; datumName = "Other surface"; method = VerticalDatumType. OTHER_SURFACE; break; default: throw new AssertionError(e); } final String name = e.name(); final VerticalDatum datum = e.datum(); final VerticalCRS crs = e.crs(); - if (e.isEPSG && !name.startsWith("NAV")) { - if (e.isEPSG) { -- /* -- * BAROMETRIC and ELLIPSOIDAL uses an axis named "Height", which is not a valid -- * axis name according ISO 19111. We skip the validation test for those enums. -- */ -- Validators.validate(crs); -- } assertSame(datum, e.datum(), name); // Datum before CRS creation. assertSame(crs.getDatum(), e.datum(), name); // Datum after CRS creation. assertEquals(datumName, datum.getName().getCode(), name); - assertEquals(method, datum.getVerticalDatumType(), name); - assertEquals(axisName, crs.getCoordinateSystem().getAxis(0).getName().getCode(), name); - if (!e.isEPSG) { // Because the information is not in EPSG database 9.x. - assertEquals(method, datum.getRealizationMethod().orElse(null), name); ++ if (method != null) { ++ assertEquals(method, datum.getVerticalDatumType(), name); + } + assertEquals(axisName, crs.getCoordinateSystem().getAxis(0).getName().getCode(), name); } } @@@ -284,7 -287,7 +273,6 @@@ final TemporalDatum datum = e.datum(); final TemporalCRS crs = e.crs(); final Date origin = datum.getOrigin(); -- Validators.validate(crs); assertSame(datum, e.datum(), name); // Datum before CRS creation. assertSame(crs.getDatum(), e.datum(), name); // Datum after CRS creation. assertEquals(epoch, dateFormat.format(origin), name); diff --cc endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/ConsistencyTest.java index b62308cb44,e111d7bd47..03d9b0cfc8 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/ConsistencyTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/ConsistencyTest.java @@@ -22,7 -22,7 +22,6 @@@ import javax.measure.Quantity import javax.measure.Unit; import javax.measure.UnitConverter; import org.opengis.metadata.Identifier; --import org.opengis.util.CodeList; import org.opengis.util.FactoryException; import org.opengis.util.NoSuchIdentifierException; import org.opengis.referencing.crs.CoordinateReferenceSystem;
