sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1684423 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/parameter/ sis-referencing/src/main/jav...
Date Tue, 09 Jun 2015 13:50:00 GMT
Author: desruisseaux
Date: Tue Jun  9 13:49:59 2015
New Revision: 1684423

URL: http://svn.apache.org/r1684423
Log:
WKT: fixed the handling of units in PrimeMeridian, and added tests.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] Tue Jun  9 13:49:59 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
[UTF-8] Tue Jun  9 13:49:59 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
[UTF-8] Tue Jun  9 13:49:59 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;
@@ -344,12 +343,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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
[UTF-8] Tue Jun  9 13:49:59 2015
@@ -819,9 +819,51 @@ 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 table below shows 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.
+     *
+     * <table class="sis">
+     * <caption>Parameters in a Projected CRS</caption>
+     * <tr>
+     *   <td>WKT 1</td>
+     *   <td>WKT 2</td>
+     * </tr><tr><td>
+     * {@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
+     * }
+     * </td><td>
+     * {@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]]
+     * }
+     * </td></tr></table></div>
      *
      * @param  formatter The formatter where to format the inner content of this WKT element.
      * @return {@code "Parameter"} or {@code "ParameterFile"}.
@@ -841,7 +883,8 @@ public class DefaultParameterValue<T> ex
          * 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) {
+        final boolean sameUnit = Objects.equals(unit, targetUnit);
+        if (isWKT1 && !sameUnit) {
             double convertedValue;
             try {
                 convertedValue = doubleValue(targetUnit);
@@ -868,10 +911,28 @@ public class DefaultParameterValue<T> ex
          * 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.
          */
-        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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
[UTF-8] Tue Jun  9 13:49:59 2015
@@ -524,8 +524,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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
[UTF-8] Tue Jun  9 13:49:59 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.
         } 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
[UTF-8] Tue Jun  9 13:49:59 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,10 @@ 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 GeographicCRS baseCRS = getBaseCRS();
+        final Unit<Angle>   unit    = ReferencingUtilities.getAngularUnit(baseCRS.getCoordinateSystem());
+        final Unit<Angle>   oldUnit = formatter.addContextualUnit(unit);
         /*
          * 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"
@@ -413,8 +411,7 @@ public class DefaultProjectedCRS extends
         if (!isBaseCRS) {
             formatCS(formatter, getCoordinateSystem(), isWKT1);
         }
-        formatter.removeContextualUnit(unit);
-        formatter.addContextualUnit(oldUnit);
+        formatter.restoreContextualUnit(unit, oldUnit);
         return isWKT1 ? WKTKeywords.ProjCS : isBaseCRS ? WKTKeywords.BaseProjCRS : WKTKeywords.ProjectedCRS;
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
[UTF-8] Tue Jun  9 13:49:59 2015
@@ -348,16 +348,24 @@ 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) || !targetUnit.equals(NonSI.DEGREE_ANGLE))
{
+            /*
+             * Note on the equals(NonSI.DEGREE_ANGLE) check:
+             *
+             * In theory, that last check is not necessary since it would be legal to format
the value in the
+             * unit of the axes of the enclosing 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's UNIT[…]
+             * element is far from the PRIMEM[…] element while it was just below it in
WKT1. Furthermore, the
+             * PRIMEM[…] unit is one source of incompatibility between various WKT1 parsers
(e.g. GDAL is not
+             * conform to OGC 01-009 and ISO 19162). So we are safer to unconditionally format
any unit other
+             * than degrees here, even if we could legally omit them.
+             */
             formatter.append(angularUnit);
         }
         return WKTKeywords.PrimeMeridian;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
[UTF-8] Tue Jun  9 13:49:59 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 = format;
+        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”,49.5],"
+                + "PARAMETER[“central_meridian”,0],"
+                + "PARAMETER[“scale_factor”,0.999877341],"
+                + "PARAMETER[“false_easting”,600000],"
+                + "PARAMETER[“false_northing”,1200000],"
+                + "UNIT[“metre”,1,AUTHORITY[“EPSG”,“9001”]],"
+                + "AXIS[“X”,EAST],"
+                + "AXIS[“Y”,NORTH],"
+                + "AUTHORITY[“EPSG”,“27581”]]");
+
+        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/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
[UTF-8] Tue Jun  9 13:49:59 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/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
[UTF-8] Tue Jun  9 13:49:59 2015
@@ -241,8 +241,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