This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/sis.git
commit 45c820c45fdb9b5349b5a501dcc04edab3f0ca22 Merge: 7b052340a2 87f745fce9 Author: Martin Desruisseaux <[email protected]> AuthorDate: Tue Nov 3 12:23:48 2026 +0100 Merge branch 'geoapi-3.1' (bug fixes mostly in referencing modules). README.md | 2 +- endorsed/build.gradle.kts | 2 +- .../org/apache/sis/feature/internal/Resources.java | 5 + .../sis/feature/internal/Resources.properties | 1 + .../sis/feature/internal/Resources_fr.properties | 1 + .../apache/sis/filter/BinaryGeometryFilter.java | 16 +- .../main/org/apache/sis/filter/DistanceFilter.java | 6 +- .../main/org/apache/sis/filter/package-info.java | 2 +- .../org/apache/sis/filter/sqlmm/ST_Transform.java | 2 +- .../org/apache/sis/filter/sqlmm/TwoGeometries.java | 19 +- .../apache/sis/geometry/wrapper/Dimensions.java | 91 +++++++++ .../apache/sis/geometry/wrapper/GeometryType.java | 6 +- .../sis/geometry/wrapper/GeometryWrapper.java | 156 ++++++++++---- .../geometry/wrapper/SpatialOperationContext.java | 192 ++++++++---------- .../apache/sis/geometry/wrapper/esri/Wrapper.java | 15 +- .../sis/geometry/wrapper/j2d/PointWrapper.java | 10 + .../geometry/wrapper/jts/GeometryTransform.java | 5 +- .../sis/geometry/wrapper/jts/GeometryWalker.java | 35 +++- .../org/apache/sis/geometry/wrapper/jts/JTS.java | 121 +---------- .../apache/sis/geometry/wrapper/jts/Wrapper.java | 96 ++++----- .../sis/filter/BinarySpatialFilterTestCase.java | 1 + .../filter/BinarySpatialFilterUsingESRI_Test.java | 1 + .../filter/BinarySpatialFilterUsingJTS_Test.java | 1 + .../BinarySpatialFilterUsingJava2D_Test.java | 1 + .../sis/geometry/wrapper/DimensionsTest.java | 95 +++++++++ .../apache/sis/geometry/wrapper/jts/JTSTest.java | 46 +++-- .../org/apache/sis/geometry/AbstractEnvelope.java | 6 +- .../pending/geoapi/referencing/MissingMethods.java | 10 +- .../main/org/apache/sis/referencing/CRS.java | 225 +++++++++++---------- .../main/org/apache/sis/referencing/CommonCRS.java | 2 +- .../referencing/EllipsoidalHeightSeparator.java | 73 +++---- .../apache/sis/referencing/IdentifiedObjects.java | 3 +- .../sis/referencing/StandardDefinitions.java | 20 +- .../main/org/apache/sis/referencing/cs/Codes.java | 55 +++-- .../sis/referencing/cs/CoordinateSystems.java | 92 ++++----- .../apache/sis/referencing/cs/package-info.java | 2 +- .../internal/shared/EllipsoidalHeightCombiner.java | 113 ++++++++--- .../shared/ReferencingFactoryContainer.java | 6 +- .../internal/shared/ReferencingUtilities.java | 15 +- .../operation/AbstractCoordinateOperation.java | 5 +- .../operation/CoordinateOperationFinder.java | 2 +- .../operation/CoordinateOperationRegistry.java | 2 +- .../operation/projection/AuthalicMercator.java | 5 +- .../referencing/operation/projection/Mercator.java | 8 +- .../operation/projection/NormalizedProjection.java | 42 ++-- .../operation/projection/TransverseMercator.java | 10 +- .../operation/projection/ZonedGridSystem.java | 8 +- .../operation/transform/AbstractMathTransform.java | 32 ++- .../operation/transform/DomainDefinition.java | 75 +++++-- .../transform/GeometryTransformException.java | 67 ++++++ .../operation/transform/MathTransforms.java | 14 +- .../operation/transform/package-info.java | 4 +- .../test/org/apache/sis/referencing/CRSTest.java | 32 ++- .../org/apache/sis/referencing/cs/CodesTest.java | 35 +++- .../shared/EllipsoidalHeightCombinerTest.java | 6 +- .../sis/storage/sql/feature/GeometryGetter.java | 41 +++- .../sis/storage/internal/InputStreamAdapter.java | 2 +- .../main/org/apache/sis/pending/jdk/JDK12.java} | 18 +- .../main/org/apache/sis/util/Classes.java | 3 +- optional/README.md | 2 +- optional/src/org.apache.sis.gui/bundle/README | 2 +- parent/overview.html | 2 +- parent/pom.xml | 4 +- 63 files changed, 1223 insertions(+), 748 deletions(-) diff --cc endorsed/build.gradle.kts index 88dac5b578,d2d53a4cd9..87bb91af04 --- a/endorsed/build.gradle.kts +++ b/endorsed/build.gradle.kts @@@ -100,7 -100,8 +100,7 @@@ dependencies */ var srcDir = file("src") // Must be the same as the hard-coded value in `BuildHelper.java`. tasks.compileJava { - options.release.set(12) // The version of both Java source code and compiled byte code. - dependsOn(":geoapi:rebuild") + options.release.set(11) // The version of both Java source code and compiled byte code. } tasks.compileTestJava { options.compilerArgs.add("-source") // "source", not "release", because we accept any target version. diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java index 09d7809012,f8d32fab1a..005037277d --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/BinaryGeometryFilter.java @@@ -206,13 -225,14 +215,14 @@@ abstract class BinaryGeometryFilter<R> */ final GeometryWrapper geometry = wrapper.apply(null); if (geometry != null) try { - final GeometryWrapper transformed = geometry.transform(optimization.findExpectedCRS(other).orElse(null)); - if (geometry != transformed) { + final CoordinateReferenceSystem crs = optimization.findExpectedCRS(other).orElse(null); + final GeometryWrapper transformed = geometry.transform(crs, true); + if (geometry != transformed && transformed.isFinite2D()) { - literal = Optimization.literal(transformed); + literal = (Literal<R,?>) Optimization.literal(transformed); if (literal == effective1) effective1 = literal; else effective2 = literal; } - } catch (IllegalArgumentException | TransformException e) { - } catch (PropertyNotFoundException | FactoryException | TransformException e) { ++ } catch (IllegalArgumentException | FactoryException | TransformException e) { optimization.warning(e, false); } /* diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java index 8320d2d727,a31bbac647..37456c446f --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/sqlmm/TwoGeometries.java @@@ -83,7 -93,7 +92,7 @@@ class TwoGeometries<R> extends SpatialF effective[1] = Optimization.literal(transformed); return recreate(effective); } - } catch (IllegalArgumentException | TransformException e) { - } catch (PropertyNotFoundException | FactoryException | TransformException e) { ++ } catch (IllegalArgumentException | FactoryException | TransformException e) { optimization.warning(e, false); } } diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java index 496824204f,08f6552d25..07f2e5cd6a --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryWrapper.java @@@ -27,26 -27,36 +27,31 @@@ import javax.measure.quantity.Length import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.CoordinateOperation; -import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; import org.opengis.util.FactoryException; + import org.apache.sis.geometry.AbstractEnvelope; import org.apache.sis.geometry.GeneralEnvelope; + import org.apache.sis.feature.internal.Resources; import org.apache.sis.filter.sqlmm.SQLMM; import org.apache.sis.referencing.CRS; - import org.apache.sis.referencing.operation.transform.MathTransforms; + import org.apache.sis.referencing.operation.transform.DomainDefinition; + import org.apache.sis.referencing.operation.transform.AbstractMathTransform; import org.apache.sis.referencing.operation.transform.TransformFactoryException; - import org.apache.sis.referencing.internal.shared.ReferencingUtilities; + import org.apache.sis.referencing.operation.transform.GeometryTransformException; + import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.Classes; import org.apache.sis.util.Debug; import org.apache.sis.util.UnconvertibleObjectException; import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.util.resources.Errors; + import org.apache.sis.util.logging.Logging; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import java.util.Set; -import org.opengis.geometry.Geometry; -import org.opengis.geometry.Boundary; -import org.opengis.geometry.TransfiniteSet; -import org.opengis.geometry.complex.Complex; -import org.opengis.filter.SpatialOperatorName; -import org.opengis.filter.DistanceOperatorName; -import org.opengis.coordinate.MismatchedDimensionException; +// Specific to the main branch: +import org.apache.sis.pending.geoapi.geometry.Geometry; +import org.apache.sis.pending.geoapi.filter.SpatialOperatorName; +import org.apache.sis.pending.geoapi.filter.DistanceOperatorName; /** @@@ -159,8 -178,9 +173,8 @@@ public abstract class GeometryWrapper e * * @return the coordinate dimension. */ - public int getCoordinateDimension() { - return Geometries.BIDIMENSIONAL; - @Override + public final int getCoordinateDimension() { + return getCoordinateDimensions().count; } /** @@@ -550,13 -573,12 +566,11 @@@ * @throws BackingStoreException if the operation failed because of another checked exception. * * @see #getCoordinateReferenceSystem() + * @see SpatialOperationContext#transform(GeometryWrapper) */ - public GeometryWrapper transform(final CoordinateReferenceSystem targetCRS) throws TransformException { - if (targetCRS == null || targetCRS == crs || crs == null) { - return this; - } - @Override + public final GeometryWrapper transform(final CoordinateReferenceSystem targetCRS) throws TransformException { try { - return transform(CRS.findOperation(crs, targetCRS, null), false); + return transform(targetCRS, false); } catch (FactoryException e) { throw new TransformFactoryException(e); } diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java index 0ab07c53ef,448b726ee6..6b46d58f76 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/SpatialOperationContext.java @@@ -400,9 -388,9 +386,9 @@@ select: if (commonCRS == null) */ final CoordinateSystem cs = geometryCRS.getCoordinateSystem(); double latitude = Double.NaN, longitude = Double.NaN; - for (int i=0; i<BIDIMENSIONAL; i++) { + for (int i = 0; i < Geometries.BIDIMENSIONAL; i++) { final CoordinateSystemAxis axis = cs.getAxis(i); - double coordinate = centroid.getCoordinate(i); + double coordinate = centroid.getOrdinate(i); coordinate = axis.getUnit().getConverterToAny(Units.DEGREE).convert(coordinate); final AxisDirection direction = axis.getDirection(); if (direction == AxisDirection.NORTH) latitude = coordinate; diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java index 6b46e04271,b17187ab17..cc1a8ecc15 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/jts/Wrapper.java @@@ -43,11 -43,9 +43,9 @@@ import org.locationtech.jts.simplify.To import org.opengis.util.FactoryException; import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; - import org.opengis.referencing.operation.CoordinateOperation; -import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; import org.apache.sis.referencing.CRS; - import org.apache.sis.referencing.operation.transform.TransformFactoryException; import org.apache.sis.geometry.DirectPosition2D; import org.apache.sis.geometry.GeneralDirectPosition; import org.apache.sis.geometry.GeneralEnvelope; diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java index 8b9e51db73,0000000000..2e633d753b mode 100644,000000..100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/pending/geoapi/referencing/MissingMethods.java @@@ -1,292 -1,0 +1,292 @@@ +/* + * 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.pending.geoapi.referencing; + +import java.util.Map; +import java.util.Collection; +import java.util.function.Function; +import java.time.temporal.Temporal; +import org.opengis.util.FactoryException; +import org.opengis.referencing.cs.*; +import org.opengis.referencing.crs.*; +import org.opengis.referencing.datum.*; +import org.opengis.metadata.quality.PositionalAccuracy; +import org.apache.sis.referencing.crs.DefaultVerticalCRS; +import org.apache.sis.referencing.crs.DefaultTemporalCRS; +import org.apache.sis.referencing.crs.DefaultEngineeringCRS; +import org.apache.sis.referencing.crs.DefaultParametricCRS; +import org.apache.sis.referencing.cs.DefaultParametricCS; +import org.apache.sis.referencing.datum.DefaultDatumEnsemble; +import org.apache.sis.referencing.datum.DefaultParametricDatum; +import org.apache.sis.referencing.factory.GeodeticObjectFactory; + + +/** + * Placeholder for methods missing in the GeoAPI 3.0 interface. + */ +public final class MissingMethods { + /** + * To be set by static {@code AbstractCRS} initializer. + */ + public static volatile Function<CoordinateReferenceSystem, DefaultDatumEnsemble<?>> datumEnsemble; + + /** + * To be set by static {@code DefaultGeodeticCRS} initializer. + */ + public static volatile Function<GeodeticCRS, DefaultDatumEnsemble<GeodeticDatum>> geodeticDatumEnsemble; + + private MissingMethods() { + } + + /** + * Returns the datum ensemble of an arbitrary CRS. + * - * @param datum the CRS from which to get a datum ensemble, or {@code null} if none. ++ * @param crs the CRS from which to get a datum ensemble, or {@code null} if none. + * @return the datum ensemble, or {@code null} if none. + */ + public static DefaultDatumEnsemble<?> getDatumEnsemble(final CoordinateReferenceSystem crs) { + final var m = datumEnsemble; + return (m != null) ? m.apply(crs) : null; + } + + /** + * Returns the datum ensemble of an arbitrary geodetic CRS. + * - * @param datum the CRS from which to get a datum ensemble, or {@code null} if none. ++ * @param crs the CRS from which to get a datum ensemble, or {@code null} if none. + * @return the datum ensemble, or {@code null} if none. + */ + public static DefaultDatumEnsemble<GeodeticDatum> getDatumEnsemble(final GeodeticCRS crs) { + final var m = geodeticDatumEnsemble; + return (m != null) ? m.apply(crs) : null; + } + + /** + * Returns the datum ensemble of an arbitrary vertical CRS. + * - * @param datum the CRS from which to get a datum ensemble, or {@code null} if none. ++ * @param crs the CRS from which to get a datum ensemble, or {@code null} if none. + * @return the datum ensemble, or {@code null} if none. + */ + public static DefaultDatumEnsemble<VerticalDatum> getDatumEnsemble(final VerticalCRS crs) { + return (crs instanceof DefaultVerticalCRS) ? ((DefaultVerticalCRS) crs).getDatumEnsemble() : null; + } + + /** + * Returns the datum ensemble of an arbitrary temporal CRS. + * - * @param datum the CRS from which to get a datum ensemble, or {@code null} if none. ++ * @param crs the CRS from which to get a datum ensemble, or {@code null} if none. + * @return the datum ensemble, or {@code null} if none. + */ + public static DefaultDatumEnsemble<TemporalDatum> getDatumEnsemble(final TemporalCRS crs) { + return (crs instanceof DefaultTemporalCRS) ? ((DefaultTemporalCRS) crs).getDatumEnsemble() : null; + } + + /** + * Returns the datum ensemble of an arbitrary engineering CRS. + * - * @param datum the CRS from which to get a datum ensemble, or {@code null} if none. ++ * @param crs the CRS from which to get a datum ensemble, or {@code null} if none. + * @return the datum ensemble, or {@code null} if none. + */ + public static DefaultDatumEnsemble<EngineeringDatum> getDatumEnsemble(final EngineeringCRS crs) { + return (crs instanceof DefaultEngineeringCRS) ? ((DefaultEngineeringCRS) crs).getDatumEnsemble() : null; + } + + /** + * Creates a datum ensemble. This method requires the <abbr>SIS</abbr> factory + * since datum ensembles were not available in GeoAPI 3.0. + * + * @param <D> the type of datum contained in the ensemble. + * @param properties name and other properties to give to the new object. + * @param members datum or reference frames which are members of the datum ensemble. + * @param accuracy inaccuracy introduced through use of the given collection of datums. + * @return the datum ensemble for the given properties. + * @throws FactoryException if the object creation failed. + */ + public static <D extends Datum> DefaultDatumEnsemble<D> createDatumEnsemble( + final Map<String,?> properties, + final Collection<? extends D> members, + final PositionalAccuracy accuracy, + DatumFactory factory) throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createDatumEnsemble(properties, members, accuracy); + } + + /** + * Creates a parametric CS. This method requires the <abbr>SIS</abbr> factory + * since parametric CRS were not available in GeoAPI 3.0. + * + * @param properties the coordinate system name, and optionally other properties. + * @param axis the axis of the parametric coordinate system. + * @param factory the factory to use for creating the coordinate system. + * @return a parametric coordinate system using the given axes. + * @throws FactoryException if the parametric object creation failed. + */ + public static DefaultParametricCS createParametricCS(final Map<String,?> properties, final CoordinateSystemAxis axis, + CSFactory factory) throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createParametricCS(properties, axis); + } + + /** + * Creates a parametric <abbr>CRS</abbr>. This method requires the <abbr>SIS</abbr> factory + * since parametric <abbr>CRS</abbr> were not available in GeoAPI 3.0. + * + * @param properties the coordinate reference system name, and optionally other properties. + * @param datum the parametric datum. + * @param cs the parametric coordinate system. + * @param factory the factory to use for creating the coordinate reference system. + * @return a parametric coordinate system using the given axes. + * @throws FactoryException if the parametric object creation failed. + */ + public static DefaultParametricCRS createParametricCRS(final Map<String,?> properties, final DefaultParametricDatum datum, + final DefaultParametricCS cs, CRSFactory factory) throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createParametricCRS(properties, datum, cs); + } + + /** + * Creates a parametric datum. This method requires the <abbr>SIS</abbr> factory + * since parametric <abbr>CRS</abbr> were not available in GeoAPI 3.0. + * + * @param properties the datum name, and optionally other properties. + * @param factory the factory to use for creating the datum. + * @return a parametric datum using the given name. + * @throws FactoryException if the parametric object creation failed. + */ + public static DefaultParametricDatum createParametricDatum(final Map<String,?> properties, DatumFactory factory) + throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createParametricDatum(properties); + } + + public static VerticalDatum createVerticalDatum(final Map<String,?> properties, final VerticalDatumType type, + final Temporal epoch, DatumFactory factory) throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createVerticalDatum(properties, type, epoch); + } + + public static GeodeticDatum createGeodeticDatum(final Map<String,?> properties, final Ellipsoid ellipsoid, + final PrimeMeridian primeMeridian, final Temporal epoch, DatumFactory factory) throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createGeodeticDatum(properties, ellipsoid, primeMeridian, epoch); + } + + public static GeographicCRS createGeographicCRS(final Map<String,?> properties, final GeodeticDatum datum, + final DefaultDatumEnsemble<GeodeticDatum> ensemble, final EllipsoidalCS cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createGeographicCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createGeographicCRS(properties, datum, ensemble, cs); + } + + public static GeodeticCRS createGeodeticCRS(final Map<String,?> properties, final GeodeticDatum datum, + final DefaultDatumEnsemble<GeodeticDatum> ensemble, final SphericalCS cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createGeocentricCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createGeodeticCRS(properties, datum, ensemble, cs); + } + + public static GeodeticCRS createGeodeticCRS(final Map<String,?> properties, final GeodeticDatum datum, + final DefaultDatumEnsemble<GeodeticDatum> ensemble, final CartesianCS cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createGeocentricCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createGeodeticCRS(properties, datum, ensemble, cs); + } + + public static VerticalCRS createVerticalCRS(final Map<String,?> properties, final VerticalDatum datum, + final DefaultDatumEnsemble<VerticalDatum> ensemble, final VerticalCS cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createVerticalCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createVerticalCRS(properties, datum, ensemble, cs); + } + + public static TemporalCRS createTemporalCRS(final Map<String,?> properties, final TemporalDatum datum, + final DefaultDatumEnsemble<TemporalDatum> ensemble, final TimeCS cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createTemporalCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createTemporalCRS(properties, datum, ensemble, cs); + } + + public static DefaultParametricCRS createParametricCRS(final Map<String,?> properties, final DefaultParametricDatum datum, + final DefaultDatumEnsemble<DefaultParametricDatum> ensemble, final DefaultParametricCS cs, CRSFactory factory) + throws FactoryException + { + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createParametricCRS(properties, datum, ensemble, cs); + } + + public static EngineeringCRS createEngineeringCRS(final Map<String,?> properties, final EngineeringDatum datum, + final DefaultDatumEnsemble<EngineeringDatum> ensemble, final CoordinateSystem cs, CRSFactory factory) + throws FactoryException + { + if (ensemble == null) { + return factory.createEngineeringCRS(properties, datum, cs); + } + if (!(factory instanceof GeodeticObjectFactory)) { + factory = GeodeticObjectFactory.provider(); + } + return ((GeodeticObjectFactory) factory).createEngineeringCRS(properties, datum, ensemble, cs); + } +} diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java index ed7dfcb8ac,024fd3188d..79505c4359 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java @@@ -88,9 -78,9 +78,8 @@@ import org.apache.sis.referencing.datum import org.apache.sis.referencing.operation.AbstractCoordinateOperation; import org.apache.sis.referencing.operation.CoordinateOperationContext; import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; - import org.apache.sis.referencing.operation.DefiningConversion; import org.apache.sis.referencing.factory.GeodeticObjectFactory; import org.apache.sis.referencing.factory.UnavailableFactoryException; -import org.apache.sis.coordinate.DefaultCoordinateMetadata; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; import org.apache.sis.metadata.iso.extent.Extents; import org.apache.sis.util.ArgumentChecks; @@@ -107,11 -97,11 +97,10 @@@ import org.apache.sis.coordinate.Defaul // Specific to the main and geoapi-3.1 branches: import org.opengis.referencing.crs.GeneralDerivedCRS; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.referencing.ObjectDomain; -import org.opengis.referencing.datum.DatumEnsemble; -import org.opengis.referencing.datum.DynamicReferenceFrame; -import org.opengis.coordinate.CoordinateMetadata; +// Specific to the main branch: +import org.apache.sis.referencing.crs.AbstractCRS; +import org.apache.sis.referencing.datum.DefaultGeodeticDatum; +import org.apache.sis.referencing.datum.DefaultVerticalDatum; - import static org.apache.sis.pending.geoapi.referencing.MissingMethods.getDatumEnsemble; /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java index 1e6a13ff7b,ec1bfaaa8b..d511d92388 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/EllipsoidalHeightSeparator.java @@@ -134,15 -122,21 +122,21 @@@ final class EllipsoidalHeightSeparator throw new IllegalArgumentException(Errors.format( Errors.Keys.UnsupportedCoordinateSystem_1, IdentifiedObjects.getName(cs, null))); } - final CommonCRS ref = CommonCRS.WGS84; - if (Utilities.equalsIgnoreMetadata(ref.geographic().getCoordinateSystem(), cs)) { - final CommonCRS c = CommonCRS.forDatum(datum, ensemble); - if (c != null) return c.geographic(); - } else if (Utilities.equalsIgnoreMetadata(ref.normalizedGeographic().getCoordinateSystem(), cs)) { - final CommonCRS c = CommonCRS.forDatum(datum, ensemble); - if (c != null) return c.normalizedGeographic(); + final var source = (GeodeticCRS) crs; + final GeodeticDatum datum = source.getDatum(); - final DatumEnsemble<GeodeticDatum> ensemble = source.getDatumEnsemble(); ++ final DefaultDatumEnsemble<GeodeticDatum> ensemble = getDatumEnsemble(source); + final CommonCRS predefined = CommonCRS.forDatum(datum, ensemble); + if (predefined != null && predefined.datum(true).equals(DatumOrEnsemble.asDatum(source))) { + // We require an equal datum because a datum change in this operation would be confusing. + boolean normalized = false; + do { + GeographicCRS candidate = normalized ? predefined.normalizedGeographic() : predefined.geographic(); + if (Utilities.equalsIgnoreMetadata(candidate.getCoordinateSystem(), cs)) { + return candidate; + } + } while ((normalized = !normalized) == true); } - return factory().createGeographicCRS(getPropertiesForModifiedCRS(crs), pseudo, (EllipsoidalCS) cs); - return factory().createGeographicCRS(getPropertiesForModifiedCRS(source), datum, ensemble, (EllipsoidalCS) cs); ++ return factory().createGeographicCRS(getPropertiesForModifiedCRS(source), DatumOrEnsemble.asDatum(source), (EllipsoidalCS) cs); } /* * In the projected CRS case, in addition of reducing the number of dimensions in the CartesianCS, @@@ -166,7 -161,15 +161,15 @@@ getPropertiesForModifiedCRS(projection), projection.getMethod(), null, projection.getParameterValues()); - return factory().createProjectedCRS(getPropertiesForModifiedCRS(crs), baseCRS, projection, (CartesianCS) cs); + return factory().createProjectedCRS(getPropertiesForModifiedCRS(source), baseCRS, projection, (CartesianCS) cs); + } + /* + * Horizontal engineering CRS requested. The axis directions have already been verified by `accept(…)`. + */ + if (crs instanceof EngineeringCRS) { + final var source = (EngineeringCRS) crs; + return factory().createEngineeringCRS( - getPropertiesForModifiedCRS(source), source.getDatum(), source.getDatumEnsemble(), cs); ++ getPropertiesForModifiedCRS(source), DatumOrEnsemble.asDatum(source), cs); } throw new IllegalArgumentException(Errors.format(Errors.Keys.UnsupportedType_1, crs.getClass())); } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java index b6e6aeb716,37c7de7a2f..3133460464 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/EllipsoidalHeightCombiner.java @@@ -35,11 -36,24 +37,18 @@@ import org.opengis.referencing.datum.Ve import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.apache.sis.referencing.IdentifiedObjects; + import org.apache.sis.referencing.cs.CoordinateSystems; import org.apache.sis.referencing.datum.DatumOrEnsemble; + import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.metadata.iso.extent.Extents; + import org.apache.sis.system.Loggers; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ArraysExt; + import org.apache.sis.util.Classes; + import org.apache.sis.util.logging.Logging; + import org.apache.sis.util.resources.Errors; + import org.apache.sis.util.internal.shared.Constants; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.referencing.ObjectDomain; - -// Specific to the geoapi-3.1 branch: -import org.opengis.referencing.crs.GeographicCRS; - /** * A class in charges of combining two-dimensional geographic or projected CRS with an ellipsoidal height into a @@@ -137,20 -143,32 +138,32 @@@ public final class EllipsoidalHeightCom axes[axisPosition++ ] = cs2D.getAxis(0); axes[axisPosition++ ] = cs2D.getAxis(1); axes[axisPosition %= 3] = vertical.getCoordinateSystem().getAxis(0); - final Map<String,?> csProps = IdentifiedObjects.getProperties(cs2D, CoordinateSystem.IDENTIFIERS_KEY); - final Map<String,?> crsProps = (components.length == 2) ? properties - : IdentifiedObjects.getProperties(crs, CoordinateReferenceSystem.IDENTIFIERS_KEY); + final String epsgCode = getEpsgCode(cs2D, axes); + /* + * If the 3D CRS created in this block will be the CRS to return, the `properties` given in + * argument to this method are used directly. Otherwise we need to derive something else. + * Current implementation reuses the properties of the two-dimensional CRS. + */ + final Map<String, ?> crsProps = (components.length == 2) + ? properties : ReferencingUtilities.getPropertiesForModifiedCRS(crs); if (crs instanceof GeodeticCRS) { final var geod = (GeodeticCRS) crs; - final EllipsoidalCS cs3D; - cs3D = factories.getCSFactory() .createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]); - crs = factories.getCRSFactory().createGeographicCRS(crsProps, DatumOrEnsemble.asDatum(geod), cs3D); - } else { - final ProjectedCRS proj = (ProjectedCRS) crs; + EllipsoidalCS cs3D = null; + if (epsgCode != null) try { + cs3D = factories.getCSAuthorityFactory().createEllipsoidalCS(epsgCode); + } catch (NoSuchAuthorityCodeException e) { + warning(e); + } + if (cs3D == null) { + cs3D = factories.getCSFactory().createEllipsoidalCS( + ReferencingUtilities.getPropertiesForModifiedCRS(cs2D), axes[0], axes[1], axes[2]); + } - crs = factories.getCRSFactory().createGeographicCRS(crsProps, geod.getDatum(), geod.getDatumEnsemble(), cs3D); ++ crs = factories.getCRSFactory().createGeographicCRS(crsProps, DatumOrEnsemble.asDatum(geod), cs3D); + } else if (crs instanceof ProjectedCRS) { + final var proj = (ProjectedCRS) crs; GeographicCRS base = proj.getBaseCRS(); if (base.getCoordinateSystem().getDimension() == 2) { - base = (GeographicCRS) createCompoundCRS( - IdentifiedObjects.getProperties(base, GeographicCRS.IDENTIFIERS_KEY), base, vertical); + base = (GeographicCRS) createCompoundCRS(ReferencingUtilities.getPropertiesForModifiedCRS(base), base, vertical); } /* * In Apache SIS implementation, the Conversion contains the source and target CRS together with @@@ -221,11 -277,13 +272,11 @@@ ArgumentChecks.ensureNonNullElement("components", i, crs); if (i != 0) name.append(" + "); name.append(crs.getName().getCode()); - for (ObjectDomain obj : crs.getDomains()) { - domain = Extents.intersection(domain, obj.getDomainOfValidity()); - } + domain = Extents.intersection(domain, crs.getDomainOfValidity()); } - final var properties = new HashMap<String,Object>(4); + final var properties = new HashMap<String, Object>(4); properties.put(CoordinateReferenceSystem.NAME_KEY, name.toString()); - properties.put(ObjectDomain.DOMAIN_OF_VALIDITY_KEY, domain); + properties.put(CoordinateReferenceSystem.DOMAIN_OF_VALIDITY_KEY, domain); return properties; } } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java index 5f35e8ce3f,054c17b0bf..2a34bb1433 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/shared/ReferencingUtilities.java @@@ -201,10 -147,7 +201,7 @@@ public final class ReferencingUtilitie * @see org.apache.sis.referencing.internal.VerticalDatumTypes#ELLIPSOIDAL */ public static boolean isEllipsoidalHeight(final VerticalDatum datum) { - if (datum != null) { - return VerticalDatumTypes.ellipsoidal(datum.getVerticalDatumType()); - } - return false; - return (datum != null) && datum.getRealizationMethod().filter(VerticalDatumTypes::ellipsoidal).isPresent(); ++ return (datum != null) && VerticalDatumTypes.ellipsoidal(datum.getVerticalDatumType()); } /** @@@ -301,8 -245,8 +298,8 @@@ * @return the identified object properties. */ public static Map<String,?> getPropertiesWithoutIdentifiers(final IdentifiedObject object, final Map<String,?> overwrite) { - final Map<String,?> properties = IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY); + final Map<String, ?> properties = IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY); - final Identifier name = object.getName(); + final ReferenceIdentifier name = object.getName(); final boolean keepName = name.getCodeSpace() == null && name.getAuthority() == null; if (keepName && overwrite == null) { return properties; diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java index d85260a2d2,225aef63e6..e8cc1e34cc --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/projection/NormalizedProjection.java @@@ -50,11 -53,9 +53,9 @@@ import org.apache.sis.referencing.opera import org.apache.sis.referencing.operation.provider.MapProjection; import org.apache.sis.referencing.internal.shared.Formulas; import org.apache.sis.system.Modules; - import org.apache.sis.util.internal.shared.Constants; - import org.apache.sis.util.internal.shared.Numerics; -// Specific to the geoapi-3.1 and geoapi-4.0 branches: -import org.opengis.metadata.Identifier; +// Specific to the main branch: +import org.opengis.referencing.ReferenceIdentifier; /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java index 0000000000,734853398d..02044c58bf mode 000000,100644..100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/GeometryTransformException.java @@@ -1,0 -1,67 +1,67 @@@ + /* + * 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.referencing.operation.transform; + + import org.opengis.referencing.operation.TransformException; + + + /** + * Thrown when a transform cannot be applied on a given geometry or envelope instance. + * This exception is usually thrown when a geometric prerequisite has not been met. + * The failed check may be before any attempt to actually transform a point. + * For example, the geometry may be an instance of an unrecognized type, + * or the geometry envelope may be outside the + * {@linkplain AbstractMathTransform#getDomain transform domain}. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.8 + * @since 1.8 + */ + public class GeometryTransformException extends TransformException { + /** + * For cross-version compatibility. + */ + private static final long serialVersionUID = -9058827495784393813L; + + /** + * Creates an exception with the specified detail message. + * + * @param message the detail message, saved for later retrieval by the {@link #getMessage()} method. + */ + public GeometryTransformException(String message) { + super(message); + } + + /** + * Creates an exception with the specified cause. + * + * @param cause the cause, saved for later retrieval by the {@link #getCause()} method. + */ + public GeometryTransformException(Throwable cause) { - super(cause); ++ super(null, cause); + } + + /** + * Creates an exception with the specified detail message and cause. + * + * @param message the detail message, saved for later retrieval by the {@link #getMessage()} method. + * @param cause the cause, saved for later retrieval by the {@link #getCause()} method. + */ + public GeometryTransformException(String message, Throwable cause) { + super(message, cause); + } + } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java index fa410d70cc,81f0645bb5..02f9cf0359 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransforms.java @@@ -798,7 -798,7 +796,7 @@@ public final class MathTransforms * @throws TransformException if the domain cannot be estimated. * * @see AbstractMathTransform#getDomain(DomainDefinition) -- * @see org.opengis.referencing.operation.CoordinateOperation#getDomains() ++ * @see org.opengis.referencing.operation.CoordinateOperation#getDomainOfValidity() * * @since 1.3 */ diff --cc endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java index 1b0b56bbc6,d772cb2d83..c7337299d5 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/Classes.java @@@ -34,10 -34,8 +34,11 @@@ import java.lang.reflect.GenericDeclara import java.lang.reflect.ParameterizedType; import java.lang.reflect.Modifier; import org.opengis.annotation.UML; + import org.apache.sis.pending.jdk.JDK12; +// Specific to the main branch: +import org.opengis.util.InternationalString; + /** * Static methods working on {@link Class} objects.
