This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit f92855ab0f941c9dc45f057dc1d486642b91d6d6
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Aug 10 16:08:52 2022 +0200

    WKT of DerivedCRS should exclude semi-major and semi-minor parameters when 
they can be inferred from the geodetic datum.
    This is the same policy than the one currently applied on ProjectedCRS WKT.
---
 .../sis/referencing/crs/DefaultDerivedCRS.java     |  16 +--
 .../sis/referencing/crs/DefaultProjectedCRS.java   |  85 +------------
 .../sis/referencing/crs/ExplicitParameters.java    | 133 +++++++++++++++++++++
 3 files changed, 135 insertions(+), 99 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
index d12faa07aa..561d191d85 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
@@ -22,7 +22,6 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.opengis.parameter.GeneralParameterValue;
 import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.VerticalDatum;
@@ -46,7 +45,6 @@ import 
org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.operation.DefaultConversion;
-import org.apache.sis.referencing.operation.DefaultOperationMethod;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.internal.jaxb.referencing.SC_SingleCRS;
@@ -56,7 +54,6 @@ import 
org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.referencing.WKTKeywords;
 import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
 
@@ -567,18 +564,7 @@ public class DefaultDerivedCRS extends 
AbstractDerivedCRS<Conversion> implements
             return WKTKeywords.Fitted_CS;
         } else {
             formatter.newLine();
-            formatter.append(new FormattableObject() {     // Format inside a 
"DefiningConversion" element.
-                @Override protected String formatTo(final Formatter formatter) 
{
-                    WKTUtilities.appendName(conversion, formatter, null);
-                    formatter.newLine();
-                    
formatter.append(DefaultOperationMethod.castOrCopy(conversion.getMethod()));
-                    formatter.newLine();
-                    for (final GeneralParameterValue param : 
conversion.getParameterValues().values()) {
-                        WKTUtilities.append(param, formatter);
-                    }
-                    return WKTKeywords.DerivingConversion;
-                }
-            });
+            formatter.append(new ExplicitParameters(this, 
WKTKeywords.DerivingConversion));     // Format inside a "DefiningConversion" 
element.
             if (convention == Convention.INTERNAL || !isBaseCRS(formatter)) {
                 final CoordinateSystem cs = getCoordinateSystem();
                 formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), 
isWKT1);
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
index 46207ca1d4..6cbcacfc85 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
@@ -19,38 +19,25 @@ package org.apache.sis.referencing.crs;
 import java.util.Map;
 import javax.measure.Unit;
 import javax.measure.quantity.Angle;
-import javax.measure.quantity.Length;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.parameter.GeneralParameterDescriptor;
 import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;                 // For 
javadoc
-import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Conversion;
 import org.opengis.referencing.operation.Projection;
 import org.opengis.geometry.MismatchedDimensionException;
-import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.cs.AxesConvention;
-import org.apache.sis.referencing.operation.DefaultOperationMethod;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.referencing.WKTKeywords;
 import org.apache.sis.internal.referencing.WKTUtilities;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.logging.Logging;
-
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;
 
 
@@ -404,7 +391,7 @@ public class DefaultProjectedCRS extends 
AbstractDerivedCRS<Projection> implemen
         formatter.newLine();
         formatter.append(toFormattable(baseCRS));
         formatter.newLine();
-        final Parameters p = new Parameters(this);
+        final ExplicitParameters p = new ExplicitParameters(this, 
WKTKeywords.Conversion);
         final boolean isBaseCRS;
         if (isWKT1) {
             p.append(formatter);                        // Format outside of 
any "Conversion" element.
@@ -426,76 +413,6 @@ public class DefaultProjectedCRS extends 
AbstractDerivedCRS<Projection> implemen
                 : formatter.shortOrLong(WKTKeywords.ProjCRS, 
WKTKeywords.ProjectedCRS);
     }
 
-    /**
-     * Temporary object for formatting the projection method and parameters 
inside a {@code Conversion} element.
-     */
-    private static final class Parameters extends FormattableObject {
-        /** The conversion which specify the operation method and parameters. 
*/
-        private final Conversion conversion;
-
-        /** Semi-major and semi-minor axis lengths. */
-        private final Ellipsoid ellipsoid;
-
-        /** Creates a new temporary {@code Conversion} elements for the 
parameters of the given CRS. */
-        Parameters(final DefaultProjectedCRS crs) {
-            conversion = crs.getConversionFromBase();
-            ellipsoid = crs.getDatum().getEllipsoid();
-        }
-
-        /** Formats this {@code Conversion} element. */
-        @Override protected String formatTo(final Formatter formatter) {
-            WKTUtilities.appendName(conversion, formatter, null);
-            formatter.newLine();
-            append(formatter);
-            return WKTKeywords.Conversion;
-        }
-
-        /** Formats this {@code Conversion} element without the conversion 
name. */
-        void append(final Formatter formatter) {
-            final Unit<Length> axisUnit = ellipsoid.getAxisUnit();
-            
formatter.append(DefaultOperationMethod.castOrCopy(conversion.getMethod()));
-            formatter.newLine();
-            for (final GeneralParameterValue param : 
conversion.getParameterValues().values()) {
-                final GeneralParameterDescriptor desc = param.getDescriptor();
-                String name;
-                if (IdentifiedObjects.isHeuristicMatchForName(desc, name = 
Constants.SEMI_MAJOR) ||
-                    IdentifiedObjects.isHeuristicMatchForName(desc, name = 
Constants.SEMI_MINOR))
-                {
-                    /*
-                     * Do not format semi-major and semi-minor axis length in 
most cases,  since those
-                     * information are provided in the ellipsoid.  An 
exception to this rule occurs if
-                     * the lengths are different from the ones declared in the 
datum.
-                     */
-                    if (param instanceof ParameterValue<?>) {
-                        final double value;
-                        try {
-                            value = ((ParameterValue<?>) 
param).doubleValue(axisUnit);
-                        } catch (IllegalStateException e) {
-                            /*
-                             * May happen if the 'conversionFromBase' 
parameter group does not provide values
-                             * for "semi_major" or "semi_minor" axis length. 
This should not happen with SIS
-                             * implementation, but may happen with 
user-defined map projection implementations.
-                             * Since the intent of this check was to skip 
those parameters anyway, it is okay
-                             * for the purpose of WKT formatting if there are 
no parameters for axis lengths.
-                             */
-                            
Logging.recoverableException(getLogger(Loggers.WKT), DefaultProjectedCRS.class, 
"formatTo", e);
-                            continue;
-                        }
-                        if (Double.isNaN(value)) {
-                            continue;
-                        }
-                        final double expected = (name == Constants.SEMI_MINOR) 
  // using '==' is okay here.
-                                ? ellipsoid.getSemiMinorAxis() : 
ellipsoid.getSemiMajorAxis();
-                        if (value == expected) {
-                            continue;
-                        }
-                    }
-                }
-                WKTUtilities.append(param, formatter);
-            }
-        }
-    }
-
 
 
 
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
new file mode 100644
index 0000000000..61e0d41dbe
--- /dev/null
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
@@ -0,0 +1,133 @@
+/*
+ * 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.crs;
+
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.operation.Conversion;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.operation.DefaultOperationMethod;
+import org.apache.sis.internal.referencing.WKTKeywords;
+import org.apache.sis.internal.referencing.WKTUtilities;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.util.logging.Logging;
+
+import static java.util.logging.Logger.getLogger;
+
+
+/**
+ * Temporary object for formatting the projection method and parameters inside 
a {@code Conversion} element.
+ * This object formats only the explicit parameters. Implicit parameters 
derived from source ellipsoid are omitted.
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @version 1.3
+ * @since   0.6
+ * @module
+ */
+final class ExplicitParameters extends FormattableObject {
+    /**
+     * The conversion which specify the operation method and parameters.
+     */
+    private final Conversion conversion;
+
+    /**
+     * Semi-major and semi-minor axis lengths, or {@code null} if the datum is 
not geodetic.
+     */
+    private final Ellipsoid ellipsoid;
+
+    /**
+     * The keyword to be returned by {@link #formatTo(Formatter)}.
+     * Should be {@link WKTKeywords#Conversion} or {@link 
WKTKeywords#DerivingConversion}.
+     */
+    private final String keyword;
+
+    /**
+     * Creates a new temporary {@code Conversion} elements for the parameters 
of the given CRS.
+     */
+    ExplicitParameters(final AbstractDerivedCRS<?> crs, final String keyword) {
+        conversion = crs.getConversionFromBase();
+        final Datum datum = crs.getDatum();
+        ellipsoid = (datum instanceof GeodeticDatum) ? ((GeodeticDatum) 
datum).getEllipsoid() : null;
+        this.keyword = keyword;
+    }
+
+    /**
+     * Formats this {@code Conversion} element.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        WKTUtilities.appendName(conversion, formatter, null);
+        formatter.newLine();
+        append(formatter);
+        return keyword;
+    }
+
+    /**
+     * Formats this {@code Conversion} element without the conversion name.
+     */
+    void append(final Formatter formatter) {
+        
formatter.append(DefaultOperationMethod.castOrCopy(conversion.getMethod()));
+        formatter.newLine();
+        for (final GeneralParameterValue param : 
conversion.getParameterValues().values()) {
+            final GeneralParameterDescriptor desc = param.getDescriptor();
+            if (ellipsoid != null) {
+                String name;
+                if (IdentifiedObjects.isHeuristicMatchForName(desc, name = 
Constants.SEMI_MAJOR) ||
+                    IdentifiedObjects.isHeuristicMatchForName(desc, name = 
Constants.SEMI_MINOR))
+                {
+                    /*
+                     * Do not format semi-major and semi-minor axis length in 
most cases,  since those
+                     * information are provided in the ellipsoid.  An 
exception to this rule occurs if
+                     * the lengths are different from the ones declared in the 
datum.
+                     */
+                    if (param instanceof ParameterValue<?>) {
+                        final double value;
+                        try {
+                            value = ((ParameterValue<?>) 
param).doubleValue(ellipsoid.getAxisUnit());
+                        } catch (IllegalStateException e) {
+                            /*
+                             * May happen if the 'conversionFromBase' 
parameter group does not provide values
+                             * for "semi_major" or "semi_minor" axis length. 
This should not happen with SIS
+                             * implementation, but may happen with 
user-defined map projection implementations.
+                             * Since the intent of this check was to skip 
those parameters anyway, it is okay
+                             * for the purpose of WKT formatting if there are 
no parameters for axis lengths.
+                             */
+                            
Logging.recoverableException(getLogger(Loggers.WKT), DefaultProjectedCRS.class, 
"formatTo", e);
+                            continue;
+                        }
+                        if (Double.isNaN(value)) {
+                            continue;
+                        }
+                        final double expected = (name == Constants.SEMI_MINOR) 
  // using '==' is okay here.
+                                ? ellipsoid.getSemiMinorAxis() : 
ellipsoid.getSemiMajorAxis();
+                        if (value == expected) {
+                            continue;
+                        }
+                    }
+                }
+            }
+            WKTUtilities.append(param, formatter);
+        }
+    }
+}

Reply via email to