sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1684480 - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ core/sis-referencing/src/main/java/org/apache/sis/parameter/ core/sis-refere...
Date Tue, 09 Jun 2015 17:11:36 GMT
Author: desruisseaux
Date: Tue Jun  9 17:11:36 2015
New Revision: 1684480

URL: http://svn.apache.org/r1684480
Log:
Merged WKT bug fixes from the JDK7 branch.

Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jun  9 17:11:36 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK7:1394913-1684221
-/sis/branches/JDK8:1584960-1684220
+/sis/branches/JDK7:1394913-1684479
+/sis/branches/JDK8:1584960-1684478
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -1306,7 +1306,7 @@ public class Formatter implements Locali
     /**
      * Adds a unit to use for the next measurements of the quantity {@code Q}. The given unit will apply to
      * all WKT elements containing a value of quantity {@code Q} without their own {@code UNIT[…]} element,
-     * until the {@link #removeContextualUnit(Unit)} method is invoked with a unit of the same quantity.
+     * until the {@link #restoreContextualUnit(Unit, Unit)} method is invoked.
      *
      * <p>If the given unit is null, then this method does nothing and returns {@code null}.</p>
      *
@@ -1328,11 +1328,55 @@ public class Formatter implements Locali
     }
 
     /**
+     * Restores the contextual unit to its previous state before the call to {@link #addContextualUnit(Unit)}.
+     * This method is used in the following pattern:
+     *
+     * {@preformat java
+     *   final Unit<?> previous = formatter.addContextualUnit(unit);
+     *   // ... format some WKT elements here.
+     *   formatter.restoreContextualUnit(unit, previous);
+     * }
+     *
+     * @param  unit The value given in argument to {@code addContextualUnit(unit)} (can be {@code null}).
+     * @param  previous The value returned by {@code addContextualUnit(unit)} (can be {@code null}).
+     * @throws IllegalStateException if this method has not been invoked in the pattern documented above.
+     *
+     * @since 0.6
+     */
+    public void restoreContextualUnit(final Unit<?> unit, final Unit<?> previous) {
+        if (previous == null) {
+            if (unit != null && units.remove(unit.toSI()) != unit) {
+                /*
+                 * The unit that we removed was not the expected one. Probably the user has invoked
+                 * addContextualUnit(…) again without a matching call to restoreContextualUnit(…).
+                 * However this check does not work in Convention.WKT1_COMMON_UNITS mode, since the
+                 * map is always empty in that mode.
+                 */
+                if (!convention.usesCommonUnits()) {
+                    throw new IllegalStateException();
+                }
+            }
+        } else if (units.put(previous.toSI(), previous) != unit) {
+            /*
+             * The unit that we replaced was not the expected one. Probably the user has invoked
+             * addContextualUnit(…) again without a matching call to restoreContextualUnit(…).
+             * Note that this case should never happen in Convention.WKT1_COMMON_UNITS mode,
+             * since 'previous' should never be non-null in that mode (if the user followed
+             * the documented pattern).
+             */
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
      * Removes the unit previously added by a call to {@code addContextualUnit(unit)}.
      * If the given unit is null, then this method does nothing.
      *
      * @param unit The contextual unit to remove, or {@code null} if none.
+     *
+     * @deprecated Replaced by {@link #restoreContextualUnit(Unit, Unit)}.
      */
+    @Deprecated
     public void removeContextualUnit(final Unit<?> unit) {
         if (unit != null) {
             units.remove(unit.toSI());
@@ -1340,14 +1384,14 @@ public class Formatter implements Locali
     }
 
     /**
-     * Returns the unit to use instead than the given one, or {@code null} if there is no replacement
-     * for {@code unit}. This method searches for a unit specified by {@link #addContextualUnit(Unit)}
+     * Returns the unit to use instead than the given one, or {@code unit} if there is no replacement.
+     * This method searches for a unit specified by {@link #addContextualUnit(Unit)}
      * which {@linkplain Unit#isCompatible(Unit) is compatible} with the given unit.
      *
      * @param  <Q>  The quantity of the unit.
      * @param  unit The unit to replace by the contextual unit, or {@code null}.
      * @return A contextual unit compatible with the given unit, or {@code unit}
-     *         if no contextual unit has been found.
+     *         (which may be null) if no contextual unit has been found.
      */
     public <Q extends Quantity> Unit<Q> toContextualUnit(final Unit<Q> unit) {
         if (unit != null) {
@@ -1357,7 +1401,7 @@ public class Formatter implements Locali
                 return candidate;
             }
         }
-        return null;
+        return unit;
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -875,9 +875,10 @@ final class GeodeticObjectParser extends
         final String        name       = element.pullString("name");
         final GeographicCRS geoCRS     = parseGeoGCS(element);
         final Unit<Length>  linearUnit = parseUnit(element, SI.METRE);
-        final Conversion    conversion = parseProjection(element, linearUnit,
-                (convention == Convention.WKT1_COMMON_UNITS) ? NonSI.DEGREE_ANGLE :
-                geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class));
+        final boolean  usesCommonUnits = convention.usesCommonUnits();
+        final Conversion    conversion = parseProjection(element,
+                usesCommonUnits ? SI.METRE : linearUnit,
+                usesCommonUnits ? NonSI.DEGREE_ANGLE : geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class));
         CoordinateSystemAxis axis0 = parseAxis(element, false, linearUnit, false);
         CoordinateSystemAxis axis1 = null;
         try {

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -19,7 +19,6 @@ package org.apache.sis.internal.referenc
 import java.util.Collection;
 import java.util.logging.Logger;
 import javax.measure.unit.Unit;
-import javax.measure.unit.NonSI;
 import javax.measure.quantity.Angle;
 import org.opengis.annotation.UML;
 import org.opengis.annotation.Specification;
@@ -112,12 +111,12 @@ public final class ReferencingUtilities
      * The preference will be given to the longitude axis, if found.
      *
      * @param  cs The coordinate system from which to get the angular unit, or {@code null}.
-     * @return The angular unit, of {@link NonSI#DEGREE_ANGLE} if no angular unit was found.
+     * @return The angular unit, of {@code null} if no angular unit was found.
      *
      * @since 0.6
      */
     public static Unit<Angle> getAngularUnit(final CoordinateSystem cs) {
-        Unit<Angle> unit = NonSI.DEGREE_ANGLE;
+        Unit<Angle> unit = null;
         if (cs != null) {
             for (int i = cs.getDimension(); --i>=0;) {
                 final CoordinateSystemAxis axis = cs.getAxis(i);

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -17,7 +17,6 @@
 package org.apache.sis.parameter;
 
 import java.util.Map;
-import javax.measure.unit.Unit;
 import org.opengis.util.InternationalString;
 import org.opengis.parameter.ParameterDirection;
 import org.opengis.parameter.ParameterDescriptor;
@@ -345,12 +344,7 @@ public abstract class AbstractParameterD
             if (defaultValue != null) {
                 formatter.appendAny(defaultValue);
             }
-            final Unit<?> unit = ((ParameterDescriptor<?>) this).getUnit();
-            if (unit != null) {
-                if (!formatter.getConvention().isSimplified() || !unit.equals(formatter.toContextualUnit(unit))) {
-                    formatter.append(unit);
-                }
-            }
+            formatter.append(((ParameterDescriptor<?>) this).getUnit());
         }
         return WKTKeywords.Parameter;
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -477,6 +477,13 @@ public class DefaultParameterValue<T> ex
     }
 
     /**
+     * Returns {@code true} if the given value is an instance of one of the types documented in {@link #valueFile()}.
+     */
+    private static boolean isFile(final Object value) {
+        return (value instanceof URI || value instanceof URL || value instanceof File);
+    }
+
+    /**
      * Returns the exception to throw when an incompatible method is invoked for the value type.
      */
     private IllegalStateException incompatibleValue(final Object value) {
@@ -815,9 +822,47 @@ public class DefaultParameterValue<T> ex
      *   Parameter["False easting", 0.0, LengthUnit["metre", 1]]
      * }
      *
-     * <div class="note"><b>Compatibility note:</b>
-     * Version 1 of WKT format did not specified the parameter unit explicitely.
-     * Instead, the unit was inherited from the enclosing element.</div>
+     * <div class="section">Unit of measurement</div>
+     * The units of measurement were never specified in WKT 1 format, and are optional in WKT 2 format.
+     * If the units are not specified, then they are inferred from the context.
+     * Typically, parameter values that are lengths are given in the unit for the projected CRS axes
+     * while parameter values that are angles are given in the unit for the base geographic CRS.
+     *
+     * <div class="note"><b>Example:</b>
+     * The snippet below show WKT representations of the map projection parameters of a projected CRS
+     * (most other elements are omitted). The map projection uses a <cite>"Latitude of natural origin"</cite>
+     * parameters which is set to 52 <strong>grads</strong>, as defined in the {@code UNIT[…]} element of the
+     * enclosing CRS. A similar rule applies to <cite>“False easting”</cite> and <cite>“False northing”</cite>
+     * parameters, which are in kilometres in this example.
+     *
+     * <p><b>WKT 1:</b></p>
+     * {@preformat wkt
+     *   PROJCS[…,
+     *     GEOGCS[…,
+     *       UNIT[“grad”, 0.015707963267948967]],       // Unit for all angles
+     *     PROJECTION[“Lambert_Conformal_Conic_1SP”]
+     *     PARAMETER[“latitude_of_origin”, 52.0],       // In grads
+     *     PARAMETER[“scale_factor”, 0.99987742],
+     *     PARAMETER[“false_easting”, 600.0],           // In kilometres
+     *     PARAMETER[“false_northing”, 2200.0],         // In kilometres
+     *     UNIT[“km”, 1000]]                            // Unit for all lengths
+     * }
+     *
+     * <p><b>WKT 2:</b></p>
+     * {@preformat wkt
+     *   ProjectedCRS[…
+     *     BaseGeodCRS[…
+     *       AngleUnit[“grad”, 0.015707963267948967]],
+     *     Conversion["Lambert zone II",
+     *       Method["Lambert Conic Conformal (1SP)"],
+     *       Parameter["Latitude of natural origin", 52.0],
+     *       Parameter["Scale factor at natural origin", 0.99987742],
+     *       Parameter["False easting", 600.0],
+     *       Parameter["False northing", 2200.0]],
+     *     CS["Cartesian", 2],
+     *       LengthUnit["km", 1000]]
+     * }
+     * </div>
      *
      * @param  formatter The formatter where to format the inner content of this WKT element.
      * @return {@code "Parameter"} or {@code "ParameterFile"}.
@@ -836,36 +881,55 @@ public class DefaultParameterValue<T> ex
          * If this parameter value does not use the same unit, then we must convert it.
          * Otherwise we can write the value as-is.
          */
-        final Unit<?> unit = getUnit();  // Gives to users a chance to override this property.
-        if (isWKT1 && targetUnit != null) {
-            double convertedValue;
-            try {
-                convertedValue = doubleValue(targetUnit);
-            } catch (IllegalStateException exception) {
-                // May happen if a parameter is mandatory (e.g. "semi-major")
-                // but no value has been set for this parameter.
-                formatter.setInvalidWKT(descriptor, exception);
-                convertedValue = Double.NaN;
-            }
+        final T       value = getValue();   // Gives to users a chance to override this property.
+        final Unit<?> unit  = getUnit();    // Gives to users a chance to override this property.
+        double convertedValue = Double.NaN;
+        boolean sameUnit = Objects.equals(unit, targetUnit);
+        if (!sameUnit) try {
+            convertedValue = doubleValue(targetUnit);
+            sameUnit = (value instanceof Number) && ((Number) value).doubleValue() == convertedValue;
+        } catch (IllegalStateException exception) {
+            // May happen if a parameter is mandatory (e.g. "semi-major")
+            // but no value has been set for this parameter.
+            formatter.setInvalidWKT(descriptor, exception);
+        }
+        if (isWKT1 && !sameUnit) {
             formatter.append(convertedValue);
+        } else if (!isWKT1 && (unit == null) && isFile(value)) {
+            formatter.append(value.toString(), null);
+            return WKTKeywords.ParameterFile;
         } else {
-            final T value = getValue();  // Gives to users a chance to override this property.
-            if (!isWKT1 && (unit == null) && (value instanceof URI || value instanceof URL || value instanceof File)) {
-                formatter.append(value.toString(), null);
-                return WKTKeywords.ParameterFile;
-            }
             formatter.appendAny(value);
         }
         /*
          * In the WKT 2 specification, the unit and the identifier are optional but recommended.
          * We follow that recommendation in strict WKT2 mode, but omit them in non-strict modes.
          * The only exception is when the parameter unit is not the same than the contextual unit,
-         * in which case we have no choice: we must format that unit.
+         * in which case we have no choice: we must format that unit, unless the numerical value
+         * is identical in both units (typically the 0 value).
          */
-        if (unit != null && !isWKT1 && (!convention.isSimplified() || !unit.equals(targetUnit))) {
+        if (!isWKT1 && (!sameUnit || !convention.isSimplified() || !hasContextualUnit(formatter))) {
             formatter.append(unit);
             // ID will be added by the Formatter itself.
         }
         return WKTKeywords.Parameter;
     }
+
+    /**
+     * Returns {@code true} if the given formatter has contextual units, in which case the WKT format can omit
+     * the unit of measurement. The contextual units may be defined either in the direct parent or in the parent
+     * of the parent, depending if we are formatting WKT1 or WKT2 respectively. This is because WKT2 wraps the
+     * parameters in an additional {@code CONVERSION[…]} element which is not present in WKT1.
+     *
+     * <p>Taking the example documented in {@link #formatTo(Formatter)}:</p>
+     * <ul>
+     *   <li>in WKT 1, {@code PROJCS[…]} is the immediate parent of {@code PARAMETER[…]}, but</li>
+     *   <li>in WKT 2, {@code ProjectedCRS[…]} is the parent of {@code Conversion[…]},
+     *       which is the parent of {@code Parameter[…]}.</li>
+     * </ul>
+     */
+    private static boolean hasContextualUnit(final Formatter formatter) {
+        return formatter.hasContextualUnit(1) ||    // In WKT1
+               formatter.hasContextualUnit(2);      // In WKT2
+    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -41,7 +41,6 @@ import org.apache.sis.io.wkt.Formatter;
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;
-import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk7.Objects;
@@ -323,7 +322,9 @@ public class AbstractCRS extends Abstrac
      * @throws IllegalStateException If the coordinate system has already been set.
      */
     final void setCoordinateSystem(final String name, final CoordinateSystem cs) {
-        if (cs != null && canSetProperty(AbstractCRS.class, "setCoordinateSystem", name, coordinateSystem != null)) {
+        if (cs != null && ReferencingUtilities.canSetProperty(AbstractCRS.class,
+                "setCoordinateSystem", name, coordinateSystem != null))
+        {
             coordinateSystem = cs;
         }
     }
@@ -468,13 +469,14 @@ public class AbstractCRS extends Abstrac
         formatter.newLine();
         final boolean isWKT1 = formatter.getConvention().majorVersion() == 1;
         if (isWKT1 || !isBaseCRS(formatter)) {
-            formatCS(formatter, getCoordinateSystem(), isWKT1);
+            final CoordinateSystem cs = getCoordinateSystem();
+            formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);
         }
         return keyword;
     }
 
     /**
-     * Returns {@code true} if the given formatter is in the process of formatting the base CRS of a
+     * Returns {@code true} if the given formatter is in the process of formatting the base CRS of an
      * {@link AbstractDerivedCRS}. In such case, the coordinate system axes shall not be formatted.
      *
      * <p>This method should return {@code true} when {@code this} CRS is the value returned by
@@ -495,15 +497,19 @@ public class AbstractCRS extends Abstrac
      * because ISO 19162 excludes the coordinate system definition in base CRS. Note however that WKT 1 includes the
      * coordinate systems.</p>
      *
+     * <div class="note"><b>Note:</b> the {@code unit} and {@code isWKT1} arguments could be computed by this method,
+     * but are requested in order to avoid computing them twice, because the caller usually have them anyway.</div>
+     *
      * @param formatter The formatter where to append the coordinate system.
      * @param cs        The coordinate system to append.
+     * @param unit      The value of {@code ReferencingUtilities.getUnit(cs)}.
      * @param isWKT1    {@code true} if formatting WKT 1, or {@code false} for WKT 2.
      */
-    final void formatCS(final Formatter formatter, final CoordinateSystem cs, final boolean isWKT1) {
+    final void formatCS(final Formatter formatter, final CoordinateSystem cs, final Unit<?> unit, final boolean isWKT1) {
+        assert unit == ReferencingUtilities.getUnit(cs) : unit;
         assert (formatter.getConvention().majorVersion() == 1) == isWKT1 : isWKT1;
         assert isWKT1 || !isBaseCRS(formatter) : isWKT1;    // Condition documented in javadoc.
 
-        final Unit<?> unit    = ReferencingUtilities.getUnit(cs);
         final Unit<?> oldUnit = formatter.addContextualUnit(unit);
         if (isWKT1) { // WKT 1 writes unit before axes, while WKT 2 writes them after axes.
             formatter.append(unit);
@@ -524,8 +530,7 @@ public class AbstractCRS extends Abstrac
             formatter.append(unit);
             formatter.indent(-1);
         }
-        formatter.removeContextualUnit(unit);
-        formatter.addContextualUnit(oldUnit);
+        formatter.restoreContextualUnit(unit, oldUnit);
         formatter.newLine(); // For writing the ID[…] element on its own line.
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -45,6 +45,7 @@ import org.apache.sis.referencing.Abstra
 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.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.io.wkt.FormattableObject;
@@ -535,7 +536,8 @@ public class DefaultDerivedCRS extends A
                 }
             });
             if (!isBaseCRS(formatter)) {
-                formatCS(formatter, getCoordinateSystem(), isWKT1);
+                final CoordinateSystem cs = getCoordinateSystem();
+                formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);
             }
             return keyword();
         }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -17,7 +17,9 @@
 package org.apache.sis.referencing.crs;
 
 import java.util.Map;
+import javax.measure.unit.Unit;
 import javax.measure.unit.NonSI;
+import javax.measure.quantity.Angle;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -178,6 +180,7 @@ class DefaultGeodeticCRS extends Abstrac
         WKTUtilities.appendName(this, formatter, null);
         final Convention convention = formatter.getConvention();
         final boolean isWKT1 = (convention.majorVersion() == 1);
+        CoordinateSystem cs = getCoordinateSystem();
         /*
          * Unconditionally format the datum element, followed by the prime meridian.
          * The prime meridian is part of datum according ISO 19111, but is formatted
@@ -188,13 +191,16 @@ class DefaultGeodeticCRS extends Abstrac
         formatter.append(toFormattable(datum));
         formatter.newLine();
         final PrimeMeridian pm = datum.getPrimeMeridian();
+        final Unit<Angle> angularUnit = ReferencingUtilities.getAngularUnit(cs);
         if (convention != Convention.WKT2_SIMPLIFIED ||
                 ReferencingUtilities.getGreenwichLongitude(pm, NonSI.DEGREE_ANGLE) != 0)
         {
+            final Unit<Angle> oldUnit = formatter.addContextualUnit(angularUnit);
             formatter.indent(1);
             formatter.append(toFormattable(pm));
             formatter.indent(-1);
             formatter.newLine();
+            formatter.restoreContextualUnit(angularUnit, oldUnit);
         }
         /*
          * Get the coordinate system to format. This will also determine the units to write and the keyword to
@@ -205,7 +211,6 @@ class DefaultGeodeticCRS extends Abstrac
          * NOT create an instance of a subclass (because the distinction between geographic and geocentric CRS
          * is not anymore in ISO 19111:2007).
          */
-        CoordinateSystem cs = getCoordinateSystem();
         final boolean isBaseCRS;
         if (isWKT1) {
             if (!(cs instanceof EllipsoidalCS)) { // Tested first because this is the most common case.
@@ -228,12 +233,13 @@ class DefaultGeodeticCRS extends Abstrac
          * Note that even if we do not format the CS, we may still write the units if we are formatting in "simplified"
          * mode (as opposed to the more verbose mode). This looks like the opposite of what we would expect, but this is
          * because formatting the unit here allow us to avoid repeating the unit in projection parameters when this CRS
-         * is part of a ProjectedCRS.
+         * is part of a ProjectedCRS. Note however that in such case, the units to format are the angular units because
+         * the linear units will be formatted in the enclosing PROJCS[…] element.
          */
         if (!isBaseCRS) {
-            formatCS(formatter, cs, isWKT1);    // Will also format the axis unit.
+            formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);    // Will also format the axes unit.
         } else if (convention.isSimplified()) {
-            formatter.append(formatter.toContextualUnit(ReferencingUtilities.getAngularUnit(cs)));
+            formatter.append(formatter.toContextualUnit(angularUnit));
         }
         /*
          * For WKT 1, the keyword depends on the subclass: "GeogCS" for GeographicCRS or "GeocCS" for GeocentricCRS.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -44,7 +44,6 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.logging.Logging;
 
@@ -383,11 +382,13 @@ public class DefaultProjectedCRS extends
             return super.formatTo(formatter);
         }
         WKTUtilities.appendName(this, formatter, null);
-        final Convention    convention = formatter.getConvention();
-        final boolean       isWKT1     = (convention.majorVersion() == 1);
-        final GeographicCRS baseCRS    = getBaseCRS();
-        final Unit<Angle>   unit       = ReferencingUtilities.getAngularUnit(baseCRS.getCoordinateSystem());
-        final Unit<Angle>   oldUnit    = formatter.addContextualUnit(unit);
+        final boolean       isWKT1      = (formatter.getConvention().majorVersion() == 1);
+        final CartesianCS   cs          = getCoordinateSystem();
+        final GeographicCRS baseCRS     = getBaseCRS();
+        final Unit<?>       lengthUnit  = ReferencingUtilities.getUnit(cs);
+        final Unit<Angle>   angularUnit = ReferencingUtilities.getAngularUnit(baseCRS.getCoordinateSystem());
+        final Unit<Angle>   oldAngle    = formatter.addContextualUnit(angularUnit);
+        final Unit<?>       oldLength   = formatter.addContextualUnit(lengthUnit);
         /*
          * Format the enclosing base CRS. Note that WKT 1 formats a full GeographicCRS while WKT 2 formats only
          * the datum with the prime meridian (no coordinate system) and uses a different keyword ("BaseGeodCRS"
@@ -411,10 +412,10 @@ public class DefaultProjectedCRS extends
          * of another derived CRS.
          */
         if (!isBaseCRS) {
-            formatCS(formatter, getCoordinateSystem(), isWKT1);
+            formatCS(formatter, cs, lengthUnit, isWKT1);
         }
-        formatter.removeContextualUnit(unit);
-        formatter.addContextualUnit(oldUnit);
+        formatter.restoreContextualUnit(lengthUnit, oldLength);
+        formatter.restoreContextualUnit(angularUnit, oldAngle);
         return isWKT1 ? WKTKeywords.ProjCS : isBaseCRS ? WKTKeywords.BaseProjCRS : WKTKeywords.ProjectedCRS;
     }
 

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -27,6 +27,7 @@ import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.Identifier;
 import org.opengis.referencing.datum.PrimeMeridian;
+import org.opengis.referencing.crs.GeneralDerivedCRS;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.internal.jaxb.gco.Measure;
@@ -81,7 +82,7 @@ import org.apache.sis.internal.jdk7.Obje
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  *
  * @see org.apache.sis.referencing.CommonCRS#primeMeridian()
@@ -337,6 +338,57 @@ public class DefaultPrimeMeridian extend
     }
 
     /**
+     * Returns {@code true} if the given formatter is in the process of formatting the prime meridian of a base CRS
+     * of an {@link AbstractDerivedCRS}. In such case, base CRS coordinate system axes shall not be formatted, which
+     * has the consequence of bringing the {@code UNIT[…]} element right below the {@code PRIMEM[…]} one. Example:
+     *
+     * {@preformat wkt
+     *   ProjectedCRS[“NTF (Paris) / Lambert zone II”,
+     *     BaseGeodCRS[“NTF (Paris)”,
+     *       Datum[“Nouvelle Triangulation Francaise”,
+     *         Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],
+     *       PrimeMeridian[“Paris”, 2.5969213],
+     *       AngleUnit[“grade”, 0.015707963267948967]],
+     *     Conversion[“Lambert zone II”,
+     *       etc...
+     * }
+     *
+     * If we were not formatting a base CRS, we would have many lines between {@code PrimeMeridian[…]} and
+     * {@code AngleUnit[…]} in the above example, which would make less obvious that the angle unit applies
+     * also to the prime meridian. It does not bring any ambiguity from an ISO 19162 standard point of view,
+     * but historically some other softwares interpreted the {@code PRIMEM[…]} units wrongly, which is why
+     * we try to find a compromise between keeping the WKT simple and avoiding an historical ambiguity.
+     *
+     * @see org.apache.sis.referencing.crs.AbstractCRS#isBaseCRS(Formatter)
+     */
+    private static boolean isElementOfBaseCRS(final Formatter formatter) {
+        return formatter.getEnclosingElement(2) instanceof GeneralDerivedCRS;
+    }
+
+    /**
+     * Returns {@code true} if {@link #formatTo(Formatter)} should conservatively format the angular unit
+     * even if it would be legal to omit it.
+     *
+     * <div class="section">Rational</div>
+     * According the ISO 19162 standard, it is legal to omit the {@code PrimeMeridian} angular unit when
+     * that unit is the same than the unit of the axes of the enclosing {@code GeographicCRS}. However the
+     * relationship between the CRS axes and the prime meridian is less obvious in WKT2 than it was in WKT1,
+     * because the WKT2 {@code UNIT[…]} element is far from the {@code PRIMEM[…]} element while it was just
+     * below it in WKT1.   Furthermore, the {@code PRIMEM[…]} unit is one source of incompatibility between
+     * various WKT1 parsers (i.e. some popular libraries are not conform to OGC 01-009 and ISO 19162).
+     * So we are safer to unconditionally format any unit other than degrees, even if we could legally
+     * omit them.
+     *
+     * <p>However in order to keep the WKT slightly simpler in {@link Convention#WKT2_SIMPLIFIED} mode,
+     * we make an exception to the above-cited safety if the {@code UNIT[…]} element is formatted right
+     * below the {@code PRIMEM[…]} one, which happen if we are inside a base CRS.
+     * See {@link #isElementOfBaseCRS(Formatter)} for more discussion.
+     */
+    private static boolean beConservative(final Formatter formatter, final Unit<Angle> targetUnit) {
+        return !targetUnit.equals(NonSI.DEGREE_ANGLE) && !isElementOfBaseCRS(formatter);
+    }
+
+    /**
      * Formats this prime meridian as a <cite>Well Known Text</cite> {@code PrimeMeridian[…]} element.
      *
      * @return {@code "PrimeMeridian"} (WKT 2) or {@code "PrimeM"} (WKT 1).
@@ -348,16 +400,13 @@ public class DefaultPrimeMeridian extend
         super.formatTo(formatter);
         final Convention convention = formatter.getConvention();
         final boolean isWKT1 = convention.majorVersion() == 1;
-        Unit<Angle> targetUnit = formatter.toContextualUnit(NonSI.DEGREE_ANGLE);
-        if (targetUnit == null) {
-            targetUnit = NonSI.DEGREE_ANGLE;
-        }
+        final Unit<Angle> targetUnit = formatter.toContextualUnit(NonSI.DEGREE_ANGLE);
         formatter.append(isWKT1 ? getGreenwichLongitude(targetUnit) : getGreenwichLongitude());
         if (isWKT1) {
             return WKTKeywords.PrimeM;
         }
         final Unit<Angle> angularUnit = getAngularUnit();   // Gives to users a chance to override properties.
-        if (!convention.isSimplified() || !targetUnit.equals(angularUnit)) {
+        if (!convention.isSimplified() || !targetUnit.equals(angularUnit) || beConservative(formatter, targetUnit)) {
             formatter.append(angularUnit);
         }
         return WKTKeywords.PrimeMeridian;

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -23,6 +23,7 @@ import java.text.ParseException;
 import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
 import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
@@ -128,12 +129,13 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Verifies that the axes of the coordinate system are those of a projected CRS, in metres.
+     * Verifies that the axes of the coordinate system are those of a projected CRS,
+     * with (East, North) axis directions.
      */
-    private static void verifyProjectedCS(final CartesianCS cs) {
+    private static void verifyProjectedCS(final CartesianCS cs, final Unit<Length> unit) {
         assertEquals("dimension", 2, cs.getDimension());
-        assertUnboundedAxisEquals("Easting",  "E", AxisDirection.EAST,  SI.METRE, cs.getAxis(0));
-        assertUnboundedAxisEquals("Northing", "N", AxisDirection.NORTH, SI.METRE, cs.getAxis(1));
+        assertUnboundedAxisEquals("Easting",  "E", AxisDirection.EAST,  unit, cs.getAxis(0));
+        assertUnboundedAxisEquals("Northing", "N", AxisDirection.NORTH, unit, cs.getAxis(1));
     }
 
     /**
@@ -199,7 +201,7 @@ public final strictfp class GeodeticObje
      */
     @Test
     @DependsOnMethod("testGeographicCRS")
-    public void testAxisSwapping() throws ParseException {
+    public void testWithAxisSwapping() throws ParseException {
         verifyGeographicCRS(1, parse(GeographicCRS.class,
                "  GEOGCS[“WGS 84”,\n" +
                "    DATUM[“World Geodetic System 1984”,\n" +
@@ -215,11 +217,11 @@ public final strictfp class GeodeticObje
      *
      * @throws ParseException if the parsing failed.
      *
-     * @see #testImplicitAxesInSeconds()
+     * @see #testWithImplicitAxesInSeconds()
      */
     @Test
     @DependsOnMethod("testGeographicCRS")
-    public void testImplicitAxes() throws ParseException {
+    public void testWithImplicitAxes() throws ParseException {
         verifyGeographicCRS(0, parse(GeographicCRS.class,
                "  GEOGCS[“WGS 84”,\n" +
                "    DATUM[“World Geodetic System 1984”,\n" +
@@ -229,7 +231,7 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Implementation of {@link #testGeographicCRS()} and {@link #testAxisSwapping()}.
+     * Implementation of {@link #testGeographicCRS()} and {@link #testWithAxisSwapping()}.
      * This test expects no {@code AUTHORITY} element on any component.
      *
      * @param swap 1 if axes are expected to be swapped, or 0 otherwise.
@@ -279,7 +281,7 @@ public final strictfp class GeodeticObje
                 "  AXIS[“Northing”, NORTH]]");
 
         assertNameAndIdentifierEqual("Mercator test", 0, crs);
-        verifyProjectedCS(crs.getCoordinateSystem());
+        verifyProjectedCS(crs.getCoordinateSystem(), SI.METRE);
         verifyGeographicCRS(0, crs.getBaseCRS());
 
         final GeodeticDatum datum = crs.getDatum();
@@ -293,12 +295,12 @@ public final strictfp class GeodeticObje
 
         assertEquals("Mercator (variant A)", crs.getConversionFromBase().getMethod().getName().getCode());
         final ParameterValueGroup param = crs.getConversionFromBase().getParameterValues();
-        assertEquals("semi_major",   6378137.0, param.parameter("semi_major"      ).doubleValue(), STRICT);
-        assertEquals("semi_minor",   6356752.3, param.parameter("semi_minor"      ).doubleValue(), 0.1);
-        assertEquals("central_meridian", -20.0, param.parameter("central_meridian").doubleValue(), STRICT);
-        assertEquals("scale_factor",       1.0, param.parameter("scale_factor"    ).doubleValue(), STRICT);
-        assertEquals("false_easting", 500000.0, param.parameter("false_easting"   ).doubleValue(), STRICT);
-        assertEquals("false_northing",     0.0, param.parameter("false_northing"  ).doubleValue(), STRICT);
+        assertEquals("semi_major",   6378137.0, param.parameter("semi_major"      ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("semi_minor",   6356752.3, param.parameter("semi_minor"      ).doubleValue(SI   .METRE),        0.1);
+        assertEquals("central_meridian", -20.0, param.parameter("central_meridian").doubleValue(NonSI.DEGREE_ANGLE), STRICT);
+        assertEquals("scale_factor",       1.0, param.parameter("scale_factor"    ).doubleValue(Unit .ONE),          STRICT);
+        assertEquals("false_easting", 500000.0, param.parameter("false_easting"   ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("false_northing",     0.0, param.parameter("false_northing"  ).doubleValue(SI   .METRE),        STRICT);
     }
 
     /**
@@ -309,7 +311,7 @@ public final strictfp class GeodeticObje
      */
     @Test
     @DependsOnMethod("testGeographicCRS")
-    public void testNonGreenwichMeridian() throws ParseException {
+    public void testWithNonGreenwichMeridian() throws ParseException {
         String wkt = "GEOGCS[“NTF (Paris)”,\n" +
                      "  DATUM[“Nouvelle Triangulation Française (Paris)”,\n" +
                      "    SPHEROID[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]],\n" +
@@ -352,14 +354,14 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Tests the parsing of a projected CRS using parameters in grades instead than degrees.
-     * The grad units are also used for the prime meridian.
+     * Tests the parsing of a projected CRS using angular values in grades instead than degrees
+     * and in lengths in kilometres instead than metres.
      *
      * @throws ParseException if the parsing failed.
      */
     @Test
-    @DependsOnMethod({"testNonGreenwichMeridian", "testProjectedCRS"})
-    public void testGradUnitInParameters() throws ParseException {
+    @DependsOnMethod({"testWithNonGreenwichMeridian", "testProjectedCRS"})
+    public void testWithLessCommonUnits() throws ParseException {
         String wkt = "PROJCS[“NTF (Paris) / Lambert zone II”," +
                      "  GEOGCS[“NTF (Paris)”," +
                      "    DATUM[“Nouvelle Triangulation Française (Paris)”," +
@@ -370,13 +372,13 @@ public final strictfp class GeodeticObje
                      "  PROJECTION[“Lambert Conformal Conic (1SP)”]," +  // Intentional swapping of "Conformal" and "Conic".
                      "  PARAMETER[“latitude_of_origin”, 52.0]," +        // In grads.
                      "  PARAMETER[“scale_factor”, 0.99987742]," +
-                     "  PARAMETER[“false_easting”, 600000]," +
-                     "  PARAMETER[“false_northing”, 2200000]," +
-                     "  UNIT[“metre”,1]]";
+                     "  PARAMETER[“false_easting”, 600.0]," +
+                     "  PARAMETER[“false_northing”, 2200.0]," +
+                     "  UNIT[“metre”,1000]]";
 
         ProjectedCRS crs = parse(ProjectedCRS.class, wkt);
         assertNameAndIdentifierEqual("NTF (Paris) / Lambert zone II", 0, crs);
-        verifyProjectedCS(crs.getCoordinateSystem());
+        verifyProjectedCS(crs.getCoordinateSystem(), SI.KILOMETRE);
         PrimeMeridian pm = verifyNTF(crs.getDatum());
         assertEquals("angularUnit", NonSI.GRADE, pm.getAngularUnit());
         assertEquals("greenwichLongitude", 2.5969213, pm.getGreenwichLongitude(), STRICT);
@@ -385,16 +387,18 @@ public final strictfp class GeodeticObje
         assertEquals("latitude_of_origin",  52.0, param.doubleValue(), STRICT);
         /*
          * Parse again using Convention.WKT1_COMMON_UNITS and ignoring AXIS[…] elements.
-         * See the comment in testNonGreenwichMeridian for a discussion. The new aspect
-         * tested by this method is that the unit should be ignored for the parameters
-         * in addition to the prime meridian.
+         * See the comment in 'testWithNonGreenwichMeridian()' method for a discussion.
+         * The new aspect tested by this method is that the unit should be ignored
+         * for the parameters in addition to the prime meridian.
          */
-        wkt = wkt.replace("2.5969213", "2.33722917");   // Convert unit in prime meridian.
-        wkt = wkt.replace("52.0", "46.8");              // Convert unit in “latitude_of_origin” parameter.
+        wkt = wkt.replace("2.5969213", "2.33722917");       // Convert unit in prime meridian.
+        wkt = wkt.replace("52.0",      "46.8");             // Convert unit in “latitude_of_origin” parameter.
+        wkt = wkt.replace("600.0",     "600000");           // Convert unit in “false_easting” parameter.
+        wkt = wkt.replace("2200.0",    "2200000");          // Convert unit in “false_northing” parameter.
         setConvention(Convention.WKT1_COMMON_UNITS, true);
         crs = parse(ProjectedCRS.class, wkt);
         assertNameAndIdentifierEqual("NTF (Paris) / Lambert zone II", 0, crs);
-        verifyProjectedCS(crs.getCoordinateSystem());
+        verifyProjectedCS(crs.getCoordinateSystem(), SI.KILOMETRE);
         pm = verifyNTF(crs.getDatum());
         assertEquals("angularUnit", NonSI.DEGREE_ANGLE, pm.getAngularUnit());
         assertEquals("greenwichLongitude", 2.33722917, pm.getGreenwichLongitude(), STRICT);
@@ -431,12 +435,12 @@ public final strictfp class GeodeticObje
      */
     private static ParameterValue<?> verifyNTF(final ParameterValueGroup param) {
         assertEquals("Lambert Conic Conformal (1SP)", param.getDescriptor().getName().getCode());
-        assertEquals("semi_major",     6378249.2, param.parameter("semi_major"      ).doubleValue(), STRICT);
-        assertEquals("semi_minor",     6356515.0, param.parameter("semi_minor"      ).doubleValue(), 1E-12);
-        assertEquals("central_meridian",     0.0, param.parameter("central_meridian").doubleValue(), STRICT);
-        assertEquals("scale_factor",  0.99987742, param.parameter("scale_factor"    ).doubleValue(), STRICT);
-        assertEquals("false_easting",   600000.0, param.parameter("false_easting"   ).doubleValue(), STRICT);
-        assertEquals("false_northing", 2200000.0, param.parameter("false_northing"  ).doubleValue(), STRICT);
+        assertEquals("semi_major",     6378249.2, param.parameter("semi_major"      ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("semi_minor",     6356515.0, param.parameter("semi_minor"      ).doubleValue(SI   .METRE),        1E-12);
+        assertEquals("central_meridian",     0.0, param.parameter("central_meridian").doubleValue(NonSI.DEGREE_ANGLE), STRICT);
+        assertEquals("scale_factor",  0.99987742, param.parameter("scale_factor"    ).doubleValue(Unit .ONE),          STRICT);
+        assertEquals("false_easting",   600000.0, param.parameter("false_easting"   ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("false_northing", 2200000.0, param.parameter("false_northing"  ).doubleValue(SI   .METRE),        STRICT);
         return param.parameter("latitude_of_origin");
     }
 
@@ -502,11 +506,11 @@ public final strictfp class GeodeticObje
      *
      * @throws ParseException if the parsing failed.
      *
-     * @see #testImplicitAxes()
+     * @see #testWithImplicitAxes()
      */
     @Test
-    @DependsOnMethod("testImplicitAxes")
-    public void testImplicitAxesInSeconds() throws ParseException {
+    @DependsOnMethod("testWithImplicitAxes")
+    public void testWithImplicitAxesInSeconds() throws ParseException {
         final GeographicCRS crs = parse(GeographicCRS.class,
                 "GEOGCS[“NAD83 / NFIS Seconds”," +
                 "DATUM[“North_American_Datum_1983”,\n" +
@@ -576,7 +580,7 @@ public final strictfp class GeodeticObje
                 "AXIS[“Easting”,East],AXIS[“Northing”,North]]");
 
         assertNameAndIdentifierEqual("FRANCE/NTF/Lambert III", 0, crs);
-        verifyProjectedCS(crs.getCoordinateSystem());
+        verifyProjectedCS(crs.getCoordinateSystem(), SI.METRE);
         final GeographicCRS geoCRS = crs.getBaseCRS();
         assertNameAndIdentifierEqual("NTF=GR3DF97A", 0, geoCRS);    // Inherited the datum name.
 
@@ -596,12 +600,12 @@ public final strictfp class GeodeticObje
 
         final ParameterValueGroup param = crs.getConversionFromBase().getParameterValues();
         assertEquals("Lambert Conic Conformal (1SP)", param.getDescriptor().getName().getCode());
-        assertEquals("semi_major",        6378249.2, param.parameter("semi_major"        ).doubleValue(), STRICT);
-        assertEquals("semi_minor",        6356515.0, param.parameter("semi_minor"        ).doubleValue(), 1E-12);
-        assertEquals("latitude_of_origin",     44.1, param.parameter("latitude_of_origin").doubleValue(), STRICT);
-        assertEquals("central_meridian", 2.33722917, param.parameter("central_meridian"  ).doubleValue(), STRICT);
-        assertEquals("scale_factor",    0.999877499, param.parameter("scale_factor"      ).doubleValue(), STRICT);
-        assertEquals("false_easting",      600000.0, param.parameter("false_easting"     ).doubleValue(), STRICT);
-        assertEquals("false_northing",     200000.0, param.parameter("false_northing"    ).doubleValue(), STRICT);
+        assertEquals("semi_major",        6378249.2, param.parameter("semi_major"        ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("semi_minor",        6356515.0, param.parameter("semi_minor"        ).doubleValue(SI   .METRE),        1E-12);
+        assertEquals("latitude_of_origin",     44.1, param.parameter("latitude_of_origin").doubleValue(NonSI.DEGREE_ANGLE), STRICT);
+        assertEquals("central_meridian", 2.33722917, param.parameter("central_meridian"  ).doubleValue(NonSI.DEGREE_ANGLE), STRICT);
+        assertEquals("scale_factor",    0.999877499, param.parameter("scale_factor"      ).doubleValue(Unit .ONE),          STRICT);
+        assertEquals("false_easting",      600000.0, param.parameter("false_easting"     ).doubleValue(SI   .METRE),        STRICT);
+        assertEquals("false_northing",     200000.0, param.parameter("false_northing"    ).doubleValue(SI   .METRE),        STRICT);
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -18,11 +18,12 @@ package org.apache.sis.io.wkt;
 
 import java.text.ParseException;
 import org.opengis.referencing.crs.VerticalCRS;
+import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
 
 
 /**
@@ -36,6 +37,18 @@ import static org.junit.Assert.*;
 @DependsOn(GeodeticObjectParserTest.class)
 public final strictfp class WKTFormatTest extends TestCase {
     /**
+     * The instance to use for the test, or {@code null} if none.
+     */
+    private WKTFormat format;
+
+    /**
+     * An instance used by {@link #testConsistency()} for parsing the WKT.
+     * May be a different instance than {@link #format} if the two instances
+     * do not use the same {@link Convention}.
+     */
+    private WKTFormat parser;
+
+    /**
      * Verifies the condition documented in {@link WKTFormat#SHORT_DATE_PATTERN} javadoc.
      */
     @Test
@@ -53,7 +66,7 @@ public final strictfp class WKTFormatTes
      */
     @Test
     public void testParse() throws ParseException {
-        final WKTFormat format = new WKTFormat(null, null);
+        format = new WKTFormat(null, null);
         final VerticalCRS crs = (VerticalCRS) format.parseObject(
                 "VERT_CS[“Gravity-related height”,\n" +
                 "  VERT_DATUM[“Mean Sea Level”, 2005],\n" +
@@ -63,4 +76,102 @@ public final strictfp class WKTFormatTes
         GeodeticObjectParserTest.assertNameAndIdentifierEqual("Gravity-related height", 0, crs);
         GeodeticObjectParserTest.assertNameAndIdentifierEqual("Mean Sea Level", 0, crs.getDatum());
     }
+
+    /**
+     * Tests consistency between the parser and the formatter when using the WKT 1 format.
+     * This test parses a WKT, formats it then parses again. We should obtain the same result.
+     *
+     * @throws ParseException if a parsing failed.
+     */
+    @Test
+    public void testConsistencyOfWKT1() throws ParseException {
+        format = new WKTFormat(null, null);
+        format.setConvention(Convention.WKT1);
+        parser = format;
+        testConsistency();
+    }
+
+    /**
+     * Tests consistency between the parser and the formatter when using the WKT 1 format.
+     * This test parses a WKT, formats it then parses again. We should obtain the same result.
+     *
+     * @throws ParseException if a parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testConsistencyOfWKT1")
+    public void testConsistencyOfWKT1_WithCommonUnits() throws ParseException {
+        format = new WKTFormat(null, null);
+        format.setConvention(Convention.WKT1_COMMON_UNITS);
+        parser = new WKTFormat(null, null);
+        parser.setConvention(Convention.WKT1);
+        testConsistency();
+    }
+
+    /**
+     * Implementation of {@link #testConsistencyOfWKT1()} and variants.
+     *
+     * @throws ParseException if a parsing failed.
+     */
+    private void testConsistency() throws ParseException {
+        testConsistency(
+                "GEOGCS[“Tokyo”,"
+                + "DATUM[“Tokyo”,"
+                +   "SPHEROID[“Bessel 1841”,6377397.155,299.1528128,AUTHORITY[“EPSG”,“7004”]],"
+                +   "TOWGS84[-148,507,685,0,0,0,0],AUTHORITY[“EPSG”,“6301”]],"
+                + "PRIMEM[“Greenwich”,0,AUTHORITY[“EPSG”,“8901”]],"
+                + "UNIT[“DMSH”,0.0174532925199433,AUTHORITY[“EPSG”,“9108”]],"
+                + "AXIS[“Lat”,NORTH],"
+                + "AXIS[“Long”,EAST],"
+                + "AUTHORITY[“EPSG”,“4301”]]");
+
+        testConsistency(
+                "GEOGCS[“NTF (Paris)”,"
+                + "DATUM[“Nouvelle_Triangulation_Francaise”,"
+                +   "SPHEROID[“Clarke 1880 (IGN)”,6378249.2,293.466021293627,AUTHORITY[“EPSG”,“7011”]],"
+                +   "TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY[“EPSG”,“6275”]],"
+                + "PRIMEM[“Paris”,2.5969213,AUTHORITY[“EPSG”,“8903”]],"
+                + "UNIT[“grad”,0.015707963267949,AUTHORITY[“EPSG”,“9105”]],"
+                + "AXIS[“Lat”,NORTH],"
+                + "AXIS[“Long”,EAST],"
+                + "AUTHORITY[“EPSG”,“4807”]]");
+
+        testConsistency(
+                "PROJCS[“NTF (Paris) / France I”,"
+                + "GEOGCS[“NTF (Paris)”,"
+                +   "DATUM[“Nouvelle_Triangulation_Francaise”,"
+                +     "SPHEROID[“Clarke 1880 (IGN)”,6378249.2,293.466021293627,AUTHORITY[“EPSG”,“7011”]],"
+                +     "TOWGS84[-168,-60,320,0,0,0,0],"
+                +     "AUTHORITY[“EPSG”,“6275”]],"
+                +   "PRIMEM[“Paris”,2.5969213,AUTHORITY[“EPSG”,“8903”]],"
+                +   "UNIT[“grad”,0.015707963267949,AUTHORITY[“EPSG”,“9105”]],"
+                +   "AXIS[“Lat”,NORTH],"
+                +   "AXIS[“Long”,EAST],"
+                +   "AUTHORITY[“EPSG”,“4807”]],"
+                + "PROJECTION[“Lambert_Conformal_Conic_1SP”],"
+                + "PARAMETER[“latitude_of_origin”,55],"             // 55 grads = 49.5 degrees
+                + "PARAMETER[“central_meridian”,0],"
+                + "PARAMETER[“scale_factor”,0.999877341],"
+                + "PARAMETER[“false_easting”,600],"
+                + "PARAMETER[“false_northing”,1200],"
+                + "UNIT[“km”,1000],"
+                + "AXIS[“X”,EAST],"
+                + "AXIS[“Y”,NORTH]]");
+
+        testConsistency(
+                "VERT_CS[“mean sea level depth”,"
+                + "VERT_DATUM[“Mean Sea Level”,2005,AUTHORITY[“EPSG”,“5100”]],"
+                + "UNIT[“kilometre”,1000],AXIS[“Z”,DOWN]]");
+    }
+
+    /**
+     * Implementation of {@link #testConsistency()} for a single WKT.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    private void testConsistency(final String wkt) throws ParseException {
+        final Object expected = parser.parseObject(wkt);
+        final String reformat = format.format(expected);
+        final Object reparsed = format.parseObject(reformat);
+        assertEqualsIgnoreMetadata(expected, reparsed);
+    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -228,6 +228,26 @@ public final strictfp class DefaultGeogr
     }
 
     /**
+     * Tests WKT 1 formatting on a CRS using a prime meridian other than Greenwich.
+     *
+     * <p>This CRS used in this test is equivalent to {@code EPSG:4807} except for axis order,
+     * since EPSG defines (<var>latitude</var>, <var>longitude</var>) in grades.</p>
+     */
+    @Test
+    @DependsOnMethod("testWKT2")
+    public void testWKT1_ForNonGreenwich() {
+        assertWktEquals(Convention.WKT1,
+                "GEOGCS[“NTF (Paris)”,\n" +
+                "  DATUM[“Nouvelle Triangulation Francaise”,\n" +   // Formatter should replace "ç" by "c".
+                "    SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" +
+                "    PRIMEM[“Paris”, 2.5969213],\n" +
+                "  UNIT[“grade”, 0.015707963267948967],\n" +
+                "  AXIS[“Longitude”, EAST],\n" +
+                "  AXIS[“Latitude”, NORTH]]",
+                HardCodedCRS.NTF);
+    }
+
+    /**
      * Tests WKT 1 formatting using {@link Convention#WKT1_COMMON_UNITS}. That convention ignores the unit of
      * measurement in {@code PRIMEM} element, and rather unconditionally interpret the angle unit as degrees.
      * This is a violation of OGC 01-009 and ISO 19162 standards, but is required for compatibility with GDAL.

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java?rev=1684480&r1=1684479&r2=1684480&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java [UTF-8] Tue Jun  9 17:11:36 2015
@@ -94,7 +94,7 @@ public final strictfp class DefaultProje
                 "    AXIS[“Longitude”, EAST],\n" +
                 "    AXIS[“Latitude”, NORTH]],\n" +
                 "  PROJECTION[“Lambert_Conformal_Conic_1SP”, AUTHORITY[“EPSG”, “9801”]],\n" +
-                "  PARAMETER[“latitude_of_origin”, 52.0],\n" +
+                "  PARAMETER[“latitude_of_origin”, 52.0],\n" +          // In grads
                 "  PARAMETER[“central_meridian”, 0.0],\n" +
                 "  PARAMETER[“scale_factor”, 0.99987742],\n" +
                 "  PARAMETER[“false_easting”, 600000.0],\n" +
@@ -107,6 +107,37 @@ public final strictfp class DefaultProje
     }
 
     /**
+     * Tests WKT 1 formatting using {@link Convention#WKT1_COMMON_UNITS}.
+     *
+     * @throws FactoryException if the CRS creation failed.
+     */
+    @Test
+    @DependsOnMethod("testWKT1")
+    public void testWKT1_WithCommonUnits() throws FactoryException {
+        final ProjectedCRS crs = create(HardCodedCRS.NTF);
+        assertWktEquals(Convention.WKT1_COMMON_UNITS,
+                "PROJCS[“NTF (Paris) / Lambert zone II”,\n" +
+                "  GEOGCS[“NTF (Paris)”,\n" +
+                "    DATUM[“Nouvelle Triangulation Francaise”,\n" +
+                "      SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" +
+                "      PRIMEM[“Paris”, 2.33722917],\n" +                    // Note the conversion from 2.5969213 grads.
+                "    UNIT[“grade”, 0.015707963267948967],\n" +
+                "    AXIS[“Longitude”, EAST],\n" +
+                "    AXIS[“Latitude”, NORTH]],\n" +
+                "  PROJECTION[“Lambert_Conformal_Conic_1SP”, AUTHORITY[“EPSG”, “9801”]],\n" +
+                "  PARAMETER[“latitude_of_origin”, 46.8],\n" +              // Note the conversion from 52 grads.
+                "  PARAMETER[“central_meridian”, 0.0],\n" +
+                "  PARAMETER[“scale_factor”, 0.99987742],\n" +
+                "  PARAMETER[“false_easting”, 600000.0],\n" +
+                "  PARAMETER[“false_northing”, 2200000.0],\n" +
+                "  UNIT[“meter”, 1],\n" +
+                "  AXIS[“Easting”, EAST],\n" +
+                "  AXIS[“Northing”, NORTH],\n" +
+                "  AUTHORITY[“EPSG”, “27572”]]",
+                crs);
+    }
+
+    /**
      * Tests WKT 1 formatting with a somewhat convolved case where the units of the prime meridian is not
      * the same than the unit of axes. Since the axis units is what we write in the {@code UNIT[…]} element,
      * the WKT formatter need to convert the unit of prime meridian and all parameter angular values.
@@ -114,7 +145,7 @@ public final strictfp class DefaultProje
      * @throws FactoryException if the CRS creation failed.
      */
     @Test
-    @DependsOnMethod("testWKT1")
+    @DependsOnMethod("testWKT1_WithCommonUnits")
     public void testWKT1_WithMixedUnits() throws FactoryException {
         final ProjectedCRS crs = create(HardCodedCRS.NTF_NORMALIZED_AXES);
         Validators.validate(crs);   // Opportunist check.
@@ -123,12 +154,12 @@ public final strictfp class DefaultProje
                 "  GEOGCS[“NTF (Paris)”,\n" +
                 "    DATUM[“Nouvelle Triangulation Francaise”,\n" +
                 "      SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" +
-                "      PRIMEM[“Paris”, 2.33722917],\n" +                    // Note the conversion from 2.5969213 grades.
+                "      PRIMEM[“Paris”, 2.33722917],\n" +                    // Note the conversion from 2.5969213 grads.
                 "    UNIT[“degree”, 0.017453292519943295],\n" +
                 "    AXIS[“Longitude”, EAST],\n" +
                 "    AXIS[“Latitude”, NORTH]],\n" +
                 "  PROJECTION[“Lambert_Conformal_Conic_1SP”, AUTHORITY[“EPSG”, “9801”]],\n" +
-                "  PARAMETER[“latitude_of_origin”, 46.8],\n" +              // Note the conversion from 52 grades.
+                "  PARAMETER[“latitude_of_origin”, 46.8],\n" +              // Note the conversion from 52 grads.
                 "  PARAMETER[“central_meridian”, 0.0],\n" +
                 "  PARAMETER[“scale_factor”, 0.99987742],\n" +
                 "  PARAMETER[“false_easting”, 600000.0],\n" +
@@ -141,6 +172,62 @@ public final strictfp class DefaultProje
     }
 
     /**
+     * Tests WKT 2 formatting in simplified mode.
+     *
+     * @throws FactoryException if the CRS creation failed.
+     */
+    @Test
+    @DependsOnMethod("testWKT1")
+    public void testWKT2_Simplified() throws FactoryException {
+        ProjectedCRS crs = create(HardCodedCRS.NTF);
+        assertWktEquals(Convention.WKT2_SIMPLIFIED,
+                "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
+                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "    Datum[“Nouvelle Triangulation Francaise”,\n" +
+                "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
+                "      PrimeMeridian[“Paris”, 2.5969213],\n" +
+                "    Unit[“grade”, 0.015707963267948967]],\n" +
+                "  Conversion[“Lambert zone II”,\n" +
+                "    Method[“Lambert Conic Conformal (1SP)”],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0],\n" +
+                "    Parameter[“Longitude of natural origin”, 0.0],\n" +
+                "    Parameter[“Scale factor at natural origin”, 0.99987742],\n" +
+                "    Parameter[“False easting”, 600000.0],\n" +
+                "    Parameter[“False northing”, 2200000.0]],\n" +
+                "  CS[“Cartesian”, 2],\n" +
+                "    Axis[“Easting (E)”, east],\n" +
+                "    Axis[“Northing (N)”, north],\n" +
+                "    Unit[“metre”, 1],\n" +
+                "  Id[“EPSG”, 27572, URI[“urn:ogc:def:crs:EPSG::27572”]]]",
+                crs);
+        /*
+         * Try again, but with mixed units. It should force the formatter to add explicit
+         * unit declaration in PrimeMeridian[…] and some Parameter[…] elements.
+         */
+        crs = create(HardCodedCRS.NTF_NORMALIZED_AXES);
+        assertWktEquals(Convention.WKT2_SIMPLIFIED,
+                "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
+                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "    Datum[“Nouvelle Triangulation Francaise”,\n" +
+                "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269]],\n" +
+                "      PrimeMeridian[“Paris”, 2.5969213, Unit[“grade”, 0.015707963267948967]],\n" +
+                "    Unit[“degree”, 0.017453292519943295]],\n" +
+                "  Conversion[“Lambert zone II”,\n" +
+                "    Method[“Lambert Conic Conformal (1SP)”],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0, Unit[“grade”, 0.015707963267948967]],\n" +
+                "    Parameter[“Longitude of natural origin”, 0.0],\n" +
+                "    Parameter[“Scale factor at natural origin”, 0.99987742],\n" +
+                "    Parameter[“False easting”, 600000.0],\n" +
+                "    Parameter[“False northing”, 2200000.0]],\n" +
+                "  CS[“Cartesian”, 2],\n" +
+                "    Axis[“Easting (E)”, east],\n" +
+                "    Axis[“Northing (N)”, north],\n" +
+                "    Unit[“metre”, 1],\n" +
+                "  Id[“EPSG”, 27572, URI[“urn:ogc:def:crs:EPSG::27572”]]]",
+                crs);
+    }
+
+    /**
      * Tests WKT 2 formatting. Contrarily to the WKT 1 formatting, in this case it does not matter
      * if we mix the units of measurement because the unit is declared for each parameter and axis.
      *
@@ -148,7 +235,7 @@ public final strictfp class DefaultProje
      */
     @Test
     @DependsOnMethod("testWKT1")
-    public void testWKT2() throws FactoryException {
+    public void testWKT2_WithMixedUnits() throws FactoryException {
         final ProjectedCRS crs = create(HardCodedCRS.NTF_NORMALIZED_AXES);
         assertWktEquals(Convention.WKT2,
                 "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
@@ -221,7 +308,7 @@ public final strictfp class DefaultProje
      * @throws FactoryException if the CRS creation failed.
      */
     @Test
-    @DependsOnMethod("testWKT2")
+    @DependsOnMethod("testWKT2_Simplified")
     public void testWKT2_ForEquirectangular() throws FactoryException {
         final ProjectedCRS crs = new GeodeticObjectBuilder()
                 .setConversionMethod("Equirectangular")
@@ -241,8 +328,8 @@ public final strictfp class DefaultProje
                 "    Method[“Equidistant Cylindrical (Spherical)”],\n" +
                 "    Parameter[“Latitude of 1st standard parallel”, 0.0],\n" +
                 "    Parameter[“Longitude of natural origin”, 0.0],\n" +
-                "    Parameter[“False easting”, 1000.0, Unit[“metre”, 1]],\n" +
-                "    Parameter[“False northing”, 2000.0, Unit[“metre”, 1]]],\n" +
+                "    Parameter[“False easting”, 1000.0],\n" +
+                "    Parameter[“False northing”, 2000.0]],\n" +
                 "  CS[“Cartesian”, 2],\n" +
                 "    Axis[“Easting (E)”, east],\n" +
                 "    Axis[“Northing (N)”, north],\n" +



Mime
View raw message