sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1569932 [2/5] - in /sis/trunk: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/io/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java...
Date Wed, 19 Feb 2014 21:41:02 GMT
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -112,7 +112,7 @@ public enum CommonCRS {
      * World Geodetic System 1984.
      * This is the default CRS for most {@code org.apache.sis} packages.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>WMS identifier:</th>          <td>CRS:84</td></tr>
      *   <tr><th>EPSG identifiers:</th>        <td>4326 &nbsp;(<i>datum:</i> 6326, &nbsp;<i>ellipsoid:</i> 7030)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"WGS 84" &nbsp;(<i>datum:</i> "World Geodetic System 1984")</td></tr>
@@ -129,7 +129,7 @@ public enum CommonCRS {
     /**
      * World Geodetic System 1972.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>EPSG identifiers:</th>        <td>4322 &nbsp;(<i>datum:</i> 6322, &nbsp;<i>ellipsoid:</i> 7043)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"WGS 72" &nbsp;(<i>datum:</i> "World Geodetic System 1972")</td></tr>
      *   <tr><th>Abbreviations or aliases:</th><td>(<i>datum:</i> "WGS 72", &nbsp;<i>ellipsoid:</i> "NWL 10D")</td></tr>
@@ -147,7 +147,7 @@ public enum CommonCRS {
      * The ellipsoid is <cite>"GRS 1980"</cite>, also known as <cite>"International 1979"</cite>.
      * This ellipsoid is very close, but not identical, to the {@linkplain #WGS84} one.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>EPSG identifiers:</th>        <td>4258 &nbsp;(<i>datum:</i> 6258, &nbsp;<i>ellipsoid:</i> 7019)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"ETRS89" &nbsp;(<i>datum:</i> "European Terrestrial Reference System 1989", &nbsp;<i>ellipsoid:</i> "GRS 1980")</td></tr>
      *   <tr><th>Abbreviations or aliases:</th><td>"ETRF89", "EUREF89", "ETRS89-GRS80" &nbsp;(<i>ellipsoid:</i> "International 1979")</td></tr>
@@ -169,7 +169,7 @@ public enum CommonCRS {
      * The ellipsoid is <cite>"GRS 1980"</cite>, also known as <cite>"International 1979"</cite>.
      * This ellipsoid is very close, but not identical, to the {@linkplain #WGS84} one.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>WMS identifier:</th>          <td>CRS:83</td></tr>
      *   <tr><th>EPSG identifiers:</th>        <td>4269 &nbsp;(<i>datum:</i> 6269, &nbsp;<i>ellipsoid:</i> 7019)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"NAD83" &nbsp;(<i>datum:</i> "North American Datum 1983", &nbsp;<i>ellipsoid:</i> "GRS 1980")</td></tr>
@@ -190,7 +190,7 @@ public enum CommonCRS {
     /**
      * North American Datum 1927.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>WMS identifier:</th>          <td>CRS:27</td></tr>
      *   <tr><th>EPSG identifiers:</th>        <td>4267 &nbsp;(<i>datum:</i> 6267, &nbsp;<i>ellipsoid:</i> 7008)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"NAD27" &nbsp;(<i>datum:</i> "North American Datum 1927", &nbsp;<i>ellipsoid:</i> "Clarke 1866")</td></tr>
@@ -206,7 +206,7 @@ public enum CommonCRS {
     /**
      * European Datum 1950.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>EPSG identifiers:</th>        <td>4230 &nbsp;(<i>datum:</i> 6230, &nbsp;<i>ellipsoid:</i> 7022)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"ED50" &nbsp;(<i>datum:</i> "European Datum 1950", &nbsp;<i>ellipsoid:</i> "International 1924")</td></tr>
      *   <tr><th>Abbreviations or aliases:</th><td>(<i>datum:</i> "ED50", <i>ellipsoid:</i> "Hayford 1909")</td></tr>
@@ -224,7 +224,7 @@ public enum CommonCRS {
      * {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#orthodromicDistance
      * orthodromic distance computation}, which may be faster and more robust.
      *
-     * <blockquote><table class="compact" style="text-align:left">
+     * <blockquote><table class="compact">
      *   <tr><th>EPSG identifiers:</th>        <td>4047 &nbsp;(<i>datum:</i> 6047, &nbsp;<i>ellipsoid:</i> 7048)</td></tr>
      *   <tr><th>Primary names:</th>           <td>"Unspecified datum based upon the GRS 1980 Authalic Sphere"</td></tr>
      *   <tr><th>Prime meridian:</th>          <td>Greenwich</td></tr>
@@ -798,7 +798,7 @@ public enum CommonCRS {
          * Height measured above the Mean Sea Level (MSL) in metres. Can be used as an approximation of geoidal heights
          * (height measured above an equipotential surface), except that MSL are not specific to any location or epoch.
          *
-         * <blockquote><table class="compact" style="text-align:left">
+         * <blockquote><table class="compact">
          *   <tr><th>EPSG identifiers:</th>         <td>5714 &nbsp;(<i>datum:</i> 5100)</td></tr>
          *   <tr><th>Primary names:</th>            <td>"MSL height" &nbsp;(<i>datum:</i> "Mean Sea Level")</td></tr>
          *   <tr><th>Abbreviations or aliases:</th> <td>"mean sea level height" &nbsp;(<i>datum:</i> "MSL")</td></tr>
@@ -813,7 +813,7 @@ public enum CommonCRS {
         /**
          * Depth measured below the Mean Sea Level (MSL) in metres.
          *
-         * <blockquote><table class="compact" style="text-align:left">
+         * <blockquote><table class="compact">
          *   <tr><th>EPSG identifiers:</th>         <td>5715 &nbsp;(<i>datum:</i> 5100)</td></tr>
          *   <tr><th>Primary names:</th>            <td>"MSL depth" &nbsp;(<i>datum:</i> "Mean Sea Level")</td></tr>
          *   <tr><th>Abbreviations or aliases:</th> <td>"mean sea level depth" &nbsp;(<i>datum:</i> "MSL")</td></tr>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -108,7 +108,7 @@ public final class IdentifiedObjects ext
      */
     public static Set<String> getNames(final IdentifiedObject object, final Citation authority) {
         final Set<String> names = new LinkedHashSet<String>(8);
-        name(object, authority, names);
+        getName(object, authority, names);
         return names;
     }
 
@@ -145,7 +145,7 @@ public final class IdentifiedObjects ext
      * @see AbstractIdentifiedObject#getName()
      */
     public static String getName(final IdentifiedObject object, final Citation authority) {
-        return name(object, authority, null);
+        return getName(object, authority, null);
     }
 
     /**
@@ -160,7 +160,7 @@ public final class IdentifiedObjects ext
      *         or a {@linkplain GenericName#tip() name tip}), or {@code null} if no name matching the
      *         specified authority has been found.
      */
-    private static String name(final IdentifiedObject object, final Citation authority, final Collection<String> addTo) {
+    private static String getName(final IdentifiedObject object, final Citation authority, final Collection<String> addTo) {
         if (object != null) {
             Identifier identifier = object.getName();
             if (authority == null) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Properties.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Properties.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Properties.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Properties.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -67,6 +67,12 @@ final class Properties extends AbstractM
         /*[5]*/ CoordinateOperation .DOMAIN_OF_VALIDITY_KEY, // same in Datum and ReferenceSystem
         /*[6]*/ CoordinateOperation .OPERATION_VERSION_KEY,
         /*[7]*/ CoordinateOperation .COORDINATE_OPERATION_ACCURACY_KEY
+
+        /*
+         * The current implementation does not look for minimum and maximum values in ParameterDescriptor
+         * and CoordinateSystemAxis, because their interpretation depends on the unit of measurement.
+         * Including those properties in this map causes more harm than good.
+         */
     };
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -320,6 +320,10 @@ final class StandardDefinitions {
                        break;
             default:   throw new AssertionError(code);
         }
-        return new DefaultCoordinateSystemAxis(properties(code, name, null, false), abrv, dir, unit, min, max, rm);
+        final Map<String,Object> properties = properties(code, name, null, false);
+        properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, min);
+        properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, max);
+        properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, rm);
+        return new DefaultCoordinateSystemAxis(properties, abrv, dir, unit);
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -28,7 +28,7 @@ import org.opengis.referencing.cs.Cartes
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
 import org.apache.sis.referencing.AbstractReferenceSystem;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.cs.AxesConvention;
@@ -38,6 +38,7 @@ 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.metadata.MetadataUtilities.canSetProperty;
 
 // Related to JDK7
 import org.apache.sis.internal.jdk7.Objects;
@@ -284,7 +285,7 @@ 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 && ReferencingUtilities.canSetProperty(name, coordinateSystem != null)) {
+        if (cs != null && canSetProperty(name, coordinateSystem != null)) {
             coordinateSystem = cs;
         }
     }
@@ -396,41 +397,57 @@ public class AbstractCRS extends Abstrac
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
-     * The default implementation writes the following elements:
+     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> CRS into the given formatter.
+     * The default implementation writes the following elements in WKT 2 format:
      *
      * <ul>
+     *   <li>The object {@linkplain #getName() name}.</li>
      *   <li>The datum, if any.</li>
-     *   <li>The unit if all axes use the same unit. Otherwise the unit is omitted and the WKT format
-     *       is {@linkplain Formatter#setInvalidWKT(IdentifiedObject) flagged as invalid}.</li>
      *   <li>All {@linkplain #getCoordinateSystem() coordinate system}'s axis.</li>
+     *   <li>The unit if all axes use the same unit, or nothing otherwise.</li>
      * </ul>
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type (e.g. {@code "GEOGCS"}).
+     * The WKT 1 format is similar to the WKT 2 one with two differences:
+     * <ul>
+     *   <li>Units are formatted before the axes instead than after the axes.</li>
+     *   <li>If no unit can be formatted because not all axes use the same unit, then the WKT is
+     *       {@linkplain Formatter#setInvalidWKT(IdentifiedObject, Exception) flagged as invalid}.</li>
+     * </ul>
+     *
+     * @return {@inheritDoc}
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        formatDefaultWKT(formatter);
-        // Will declares the WKT as invalid.
-        return super.formatTo(formatter);
-    }
-
-    /**
-     * Default implementation of {@link #formatTo(Formatter)}.
-     * For {@link DefaultEngineeringCRS} and {@link DefaultVerticalCRS} use only.
-     */
-    final void formatDefaultWKT(final Formatter formatter) {
-        formatter.append(getDatum());
-        final Unit<?> unit = getUnit();
-        formatter.append(unit);
+        final String  keyword = super.formatTo(formatter);
         final CoordinateSystem cs = coordinateSystem;
+        final boolean isWKT1  = formatter.getConvention().majorVersion() == 1;
+        final Unit<?> unit    = ReferencingUtilities.getUnit(cs);
+        final Unit<?> oldUnit = formatter.addContextualUnit(unit);
+        formatter.newLine();
+        formatter.append(getDatum());
+        formatter.newLine();
+        if (isWKT1) { // WKT 1 writes unit before axes, while WKT 2 writes them after axes.
+            formatter.append(unit);
+            if (unit == null) {
+                formatter.setInvalidWKT(this, null);
+            }
+        } else {
+            formatter.append(cs); // The concept of CoordinateSystem was not explicit in WKT 1.
+            formatter.indent(+1);
+        }
         final int dimension = cs.getDimension();
         for (int i=0; i<dimension; i++) {
+            formatter.newLine();
             formatter.append(cs.getAxis(i));
         }
-        if (unit == null) {
-            formatter.setInvalidWKT(cs);
+        if (!isWKT1) { // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
+            formatter.newLine();
+            formatter.append(unit);
+            formatter.indent(-1);
         }
+        formatter.removeContextualUnit(unit);
+        formatter.addContextualUnit(oldUnit);
+        formatter.newLine(); // For writing the ID[…] element on its own line.
+        return keyword;
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -32,13 +32,15 @@ import org.apache.sis.referencing.cs.Axe
 import org.apache.sis.referencing.cs.DefaultCompoundCS;
 import org.apache.sis.referencing.AbstractReferenceSystem;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.referencing.WKTUtilities;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.util.collection.CheckedContainer;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Workaround;
 import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.Convention;
 
 import static org.apache.sis.util.ArgumentChecks.*;
 import static org.apache.sis.util.Utilities.deepEquals;
@@ -381,16 +383,34 @@ public class DefaultCompoundCRS extends 
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code CompoundCRS[…]} element.
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type, which is {@code "COMPD_CS"}.
+     * {@section WKT validity}
+     * The WKT version 2 format restricts compound CRS to the following components in that order:
+     *
+     * <ul>
+     *   <li>A mandatory horizontal CRS (only one of two-dimensional {@code GeographicCRS}
+     *       or {@code ProjectedCRS} or {@code EngineeringCRS}).</li>
+     *   <li>Optionally followed by a {@code VerticalCRS} or a {@code ParametricCRS} (but not both).</li>
+     *   <li>Optionally followed by a {@code TemporalCRS}.</li>
+     * </ul>
+     *
+     * SIS does not check if this CRS is compliant with the above-cited restrictions.
+     *
+     * @return {@code "CompoundCRS"} (WKT 2) or {@code "Compd_CS"} (WKT 1).
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        for (final CoordinateReferenceSystem element : components) {
+        WKTUtilities.appendName(this, formatter, null);
+        final Convention convention = formatter.getConvention();
+        final boolean isWKT1 = convention.majorVersion() == 1;
+        for (final CoordinateReferenceSystem element :
+                (isWKT1 || convention == Convention.INTERNAL) ? components : singles)
+        {
+            formatter.newLine();
             formatter.append(element);
         }
-        return "COMPD_CS";
+        formatter.newLine(); // For writing the ID[…] element on its own line.
+        return isWKT1 ? "Compd_CS" : "CompoundCRS";
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -46,14 +46,13 @@ import static org.apache.sis.util.Argume
  * </ul>
  *
  * <p><b>Used with coordinate system types:</b>
- *   {@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian},
  *   {@linkplain org.apache.sis.referencing.cs.DefaultAffineCS Affine},
- *   {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS Ellipsoidal},
- *   {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS Spherical},
+ *   {@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian},
  *   {@linkplain org.apache.sis.referencing.cs.DefaultCylindricalCS Cylindrical},
- *   {@linkplain org.apache.sis.referencing.cs.DefaultPolarCS Polar},
- *   {@linkplain org.apache.sis.referencing.cs.DefaultVerticalCS Vertical} or
  *   {@linkplain org.apache.sis.referencing.cs.DefaultLinearCS Linear}.
+ *   {@linkplain org.apache.sis.referencing.cs.DefaultPolarCS Polar},
+ *   {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS Spherical} or
+ *   {@linkplain org.apache.sis.referencing.cs.DefaultUserDefinedCS User Defined}.
  * </p>
  *
  * {@section Immutability and thread safety}
@@ -252,14 +251,13 @@ public class DefaultEngineeringCRS exten
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code EngineeringCRS[…]} element.
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type, which is {@code "LOCAL_CS"}.
+     * @return {@code "EngineeringCRS"} (WKT 2) or {@code "Local_CS"} (WKT 1).
      */
     @Override
-    public String formatTo(final Formatter formatter) { // TODO: should be protected.
-        formatDefaultWKT(formatter);
-        return "LOCAL_CS";
+    protected String formatTo(final Formatter formatter) {
+        super.formatTo(formatter);
+        return (formatter.getConvention().majorVersion() == 1) ? "Local_CS" : "EngineeringCRS";
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -18,14 +18,12 @@ package org.apache.sis.referencing.crs;
 
 import java.util.Map;
 import javax.xml.bind.annotation.XmlTransient;
-import javax.measure.unit.Unit;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.SphericalCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.internal.referencing.Legacy;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
 
@@ -211,33 +209,45 @@ public class DefaultGeocentricCRS extend
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code GeodeticCRS[…]} element.
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type, which is {@code "GEOCCS"}.
+     * <blockquote><font size="-1"><b>Example:</b> Well-Known Text (version 2)
+     * of a geocentric coordinate reference system using the WGS 84 datum.
+     *
+     * {@preformat wkt
+     *   GeodeticCRS["Geocentric",
+     *     Datum["World Geodetic System 1984",
+     *       Ellipsoid["WGS84", 6378137.0, 298.257223563, LengthUnit["metre", 1]]],
+     *       PrimeMeridian["Greenwich", 0.0, AngleUnit["degree", 0.017453292519943295]],
+     *     CS["Cartesian", 3],
+     *       Axis["(X)", geocentricX],
+     *       Axis["(Y)", geocentricY],
+     *       Axis["(Z)", geocentricZ],
+     *       LengthUnit["metre", 1]]
+     * }
+     *
+     * <p>Same coordinate reference system using WKT 1. Note that axis directions are totally different.</p>
+     *
+     * {@preformat wkt
+     *   GEOCCS["Geocentric",
+     *     DATUM["World Geodetic System 1984",
+     *       SPHEROID["WGS84", 6378137.0, 298.257223563]],
+     *     PRIMEM["Greenwich", 0.0],
+     *     UNIT["metre", 1],
+     *     AXIS["X", OTHER],
+     *     AXIS["Y", EAST],
+     *     AXIS["Z", NORTH]]
+     * }
+     * </font></blockquote>
+     *
+     * @return {@code "GeodeticCRS"} (WKT 2) or {@code "GeocCS"} (WKT 1).
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        final Unit<?> unit = getUnit();
-        final GeodeticDatum datum = getDatum();
-        formatter.append(datum);
-        formatter.append(datum.getPrimeMeridian());
-        formatter.append(unit);
-        CoordinateSystem cs = getCoordinateSystem();
-        if (formatter.getConvention().isWKT1()) {
-            if (cs instanceof CartesianCS) {
-                cs = Legacy.forGeocentricCRS((CartesianCS) cs, true);
-            } else {
-                formatter.setInvalidWKT(cs);
-            }
-        }
-        final int dimension = cs.getDimension();
-        for (int i=0; i<dimension; i++) {
-            formatter.append(cs.getAxis(i));
-        }
-        if (unit == null) {
-            formatter.setInvalidWKT(this);
+        String keyword = super.formatTo(formatter);
+        if (keyword == null) {
+            keyword = "GeocCS"; // WKT 1
         }
-        return "GEOCCS";
+        return keyword;
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.crs;
 
 import java.util.Map;
+import javax.measure.unit.Unit;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -26,7 +27,10 @@ import org.opengis.referencing.cs.Ellips
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.datum.GeodeticDatum;
+import org.apache.sis.internal.referencing.Legacy;
+import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -153,4 +157,62 @@ class DefaultGeodeticCRS extends Abstrac
     AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem cs) {
         return new DefaultGeodeticCRS(properties, datum, cs);
     }
+
+    /**
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code GeodeticCRS[…]} element.
+     * It is subclasses responsibility to overwrite this method for returning the proper keyword in WKT 1 case.
+     *
+     * @return {@code "GeodeticCRS"} (WKT 2) or {@code null} (WKT 1).
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        WKTUtilities.appendName(this, formatter, null);
+        final boolean isWKT1  = formatter.getConvention().majorVersion() == 1;
+        final Unit<?> unit    = getUnit();
+        final Unit<?> oldUnit = formatter.addContextualUnit(unit);
+        formatter.newLine();
+        formatter.append(datum);
+        formatter.newLine();
+        formatter.indent(isWKT1 ? 0 : +1);
+        formatter.append(datum.getPrimeMeridian());
+        formatter.indent(isWKT1 ? 0 : -1);
+        formatter.newLine();
+        CoordinateSystem cs = super.getCoordinateSystem();
+        if (isWKT1) { // WKT 1 writes unit before axes, while WKT 2 writes them after axes.
+            formatter.append(unit);
+            if (unit == null) {
+                formatter.setInvalidWKT(this, null);
+            }
+            /*
+             * Replaces the given coordinate system by an instance conform to the conventions used in WKT 1.
+             * Note that we can not delegate this task to subclasses, because XML unmarshalling of a geodetic
+             * CRS will NOT create an instance of a subclass (because the distinction between geographic and
+             * geocentric CRS is not anymore in ISO 19111:2007).
+             */
+            if (!(cs instanceof EllipsoidalCS)) { // Tested first because this is the most common case.
+                if (cs instanceof CartesianCS) {
+                    cs = Legacy.forGeocentricCRS((CartesianCS) cs, true);
+                } else {
+                    formatter.setInvalidWKT(cs, null);
+                }
+            }
+        } else {
+            formatter.append(cs); // The concept of CoordinateSystem was not explicit in WKT 1.
+            formatter.indent(+1);
+        }
+        final int dimension = cs.getDimension();
+        for (int i=0; i<dimension; i++) {
+            formatter.newLine();
+            formatter.append(cs.getAxis(i));
+        }
+        if (!isWKT1) { // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
+            formatter.newLine();
+            formatter.append(unit);
+            formatter.indent(-1);
+        }
+        formatter.removeContextualUnit(unit);
+        formatter.addContextualUnit(oldUnit);
+        formatter.newLine(); // For writing the ID[…] element on its own line.
+        return isWKT1 ? null : "GeodeticCRS";
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,21 +17,14 @@
 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.XmlTransient;
-import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
-import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.measure.Units;
 
 
 /**
@@ -197,48 +190,48 @@ public class DefaultGeographicCRS extend
     }
 
     /**
-     * Returns the angular unit of the specified coordinate system.
-     * The preference will be given to the longitude axis, if found.
-     */
-    private static Unit<Angle> getAngularUnit(final CoordinateSystem coordinateSystem) {
-        Unit<Angle> unit = NonSI.DEGREE_ANGLE;
-        for (int i=coordinateSystem.getDimension(); --i>=0;) {
-            final CoordinateSystemAxis axis = coordinateSystem.getAxis(i);
-            final Unit<?> candidate = axis.getUnit();
-            if (Units.isAngular(candidate)) {
-                unit = candidate.asType(Angle.class);
-                if (AxisDirection.EAST.equals(AxisDirections.absolute(axis.getDirection()))) {
-                    break; // Found the longitude axis.
-                }
-            }
-        }
-        return unit;
-    }
-
-    /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code GeodeticCRS[…]} element.
+     *
+     * <blockquote><font size="-1"><b>Example:</b> Well-Known Text (version 2)
+     * of a geographic coordinate reference system using the WGS 84 datum.
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type, which is {@code "GEOGCS"}.
+     * {@preformat wkt
+     *   GeodeticCRS["WGS 84",
+     *      Datum["World Geodetic System 1984",
+     *        Ellipsoid["WGS84", 6378137.0, 298.257223563, LengthUnit["metre", 1]]],
+     *        PrimeMeridian["Greenwich", 0.0, AngleUnit["degree", 0.017453292519943295]],
+     *      CS["ellipsoidal", 2],
+     *        Axis["Latitude", north],
+     *        Axis["Longitude", east],
+     *        AngleUnit["degree", 0.017453292519943295],
+     *      Area["World"],
+     *      BBox[-90.00, -180.00, 90.00, 180.00],
+     *      Scope["Used by GPS satellite navigation system."]
+     *      Id["EPSG", 4326, Citation["OGP"], URI["urn:ogc:def:crs:EPSG::4326"]]]
+     * }
+     *
+     * <p>Same coordinate reference system using WKT 1.</p>
+     *
+     * {@preformat wkt
+     *   GEOGCS["WGS 84"
+     *      DATUM["World Geodetic System 1984"
+     *        SPHEROID["WGS84", 6378137.0, 298.257223563]]
+     *      PRIMEM["Greenwich", 0.0]
+     *      UNIT["degree", 0.017453292519943295]
+     *      AXIS["Latitude", NORTH],
+     *      AXIS["Longitude", EAST],
+     *      AUTHORITY["EPSG", "4326"]]
+     * }
+     * </font></blockquote>
+     *
+     * @return {@code "GeodeticCRS"} (WKT 2) or {@code "GeogCS"} (WKT 1).
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        final Unit<Angle> oldUnit = formatter.getAngularUnit();
-        final Unit<Angle> unit = getAngularUnit(getCoordinateSystem());
-        final GeodeticDatum datum = getDatum();
-        formatter.setAngularUnit(unit);
-        formatter.append(datum);
-        formatter.append(datum.getPrimeMeridian());
-        formatter.append(unit);
-        final EllipsoidalCS cs = getCoordinateSystem();
-        final int dimension = cs.getDimension();
-        for (int i=0; i<dimension; i++) {
-            formatter.append(cs.getAxis(i));
-        }
-        if (!unit.equals(getUnit())) {
-            formatter.setInvalidWKT(this);
+        String keyword = super.formatTo(formatter);
+        if (keyword == null) {
+            keyword = "GeogCS"; // WKT 1
         }
-        formatter.setAngularUnit(oldUnit);
-        return "GEOGCS";
+        return keyword;
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -27,6 +27,7 @@ import org.opengis.referencing.cs.Cartes
 import org.opengis.referencing.datum.ImageDatum;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -250,4 +251,22 @@ public class DefaultImageCRS extends Abs
     final AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem cs) {
         return new DefaultImageCRS(properties, datum, (AffineCS) cs);
     }
+
+    /**
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code ImageCRS[…]} element.
+     *
+     * {@note <code>ImageCRS</code> are defined in the WKT 2 specification only.}
+     *
+     * @return {@code "ImageCRS"}.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        /*
+         * Note: super.formatTo(formatter) will usually format a DefaultImageDatum instance,
+         * which will declare this WKT has invalid if the formatter convention is a WKT 1 one.
+         * So we do not redo this check here.
+         */
+        super.formatTo(formatter);
+        return "ImageCRS";
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -29,6 +29,7 @@ import org.opengis.referencing.crs.Tempo
 import org.opengis.referencing.datum.TemporalDatum;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.measure.Units;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -293,4 +294,22 @@ public class DefaultTemporalCRS extends 
         }
         return toMillis.inverse().convert(time.getTime() - origin);
     }
+
+    /**
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code TimeCRS[…]} element.
+     *
+     * {@note <code>TimeCRS</code> is defined in the WKT 2 specification only.}
+     *
+     * @return {@code "TimeCRS"}.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        /*
+         * Note: super.formatTo(formatter) will usually format a DefaultTemporalDatum instance,
+         * which will declare this WKT has invalid if the formatter convention is a WKT 1 one.
+         * So we do not redo this check here.
+         */
+        super.formatTo(formatter);
+        return "TimeCRS";
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -229,14 +229,13 @@ public class DefaultVerticalCRS extends 
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT)</a> element.
+     * Formats this CRS as a <cite>Well Known Text</cite> {@code VerticalCRS[…]} element.
      *
-     * @param  formatter The formatter to use.
-     * @return The name of the WKT element type, which is {@code "VERT_CS"}.
+     * @return {@code "VerticalCRS"} (WKT 2) or {@code "Vert_CS"} (WKT 1).
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        formatDefaultWKT(formatter);
-        return "VERT_CS";
+        super.formatTo(formatter);
+        return (formatter.getConvention().majorVersion() == 1) ? "Vert_CS" : "VerticalCRS";
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,7 +17,7 @@
 
 /**
  * Coordinate reference system definitions as coordinate systems related to the earth through datum.
- * An explanation for this package is provided in the {@linkplain org.opengis.referencing.crs OpenGIS&reg; javadoc}.
+ * An explanation for this package is provided in the {@linkplain org.opengis.referencing.crs OpenGIS® javadoc}.
  * The remaining discussion on this page is specific to the SIS implementation.
  *
  * <p>The root class for this package is {@link org.apache.sis.referencing.crs.AbstractCRS}.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -33,6 +33,7 @@ import org.opengis.referencing.cs.AxisDi
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
@@ -180,11 +181,11 @@ public class AbstractCS extends Abstract
              */
             switch (validateAxis(direction, unit)) {
                 case INVALID_DIRECTION: {
-                    throw new IllegalArgumentException(Errors.format(
+                    throw new IllegalArgumentException(Errors.getResources(properties).getString(
                             Errors.Keys.IllegalAxisDirection_2, getClass(), direction));
                 }
                 case INVALID_UNIT: {
-                    throw new IllegalArgumentException(Errors.format(
+                    throw new IllegalArgumentException(Errors.getResources(properties).getString(
                             Errors.Keys.IllegalUnitFor_2, name, unit));
                 }
             }
@@ -199,7 +200,7 @@ public class AbstractCS extends Abstract
                     final AxisDirection other = axes[j].getDirection();
                     final AxisDirection abs = AxisDirections.absolute(other);
                     if (dir.equals(abs) && !abs.equals(AxisDirection.FUTURE)) {
-                        throw new IllegalArgumentException(Errors.format(
+                        throw new IllegalArgumentException(Errors.getResources(properties).getString(
                                 Errors.Keys.ColinearAxisDirections_2, direction, other));
                     }
                 }
@@ -276,8 +277,8 @@ public class AbstractCS extends Abstract
      * <p><b>Note for implementors:</b> since this method is invoked at construction time, it shall not depend
      * on this object's state. This method is not in public API for that reason.</p>
      *
-     * @param  direction The direction to test for compatibility.
-     * @param  unit The unit to test for compatibility.
+     * @param  direction The direction to test for compatibility (never {@code null}).
+     * @param  unit The unit to test for compatibility (never {@code null}).
      * @return {@link #VALID} if the given direction and unit are compatible with this coordinate system,
      *         {@link #DIRECTION} if the direction is invalid or {@link #UNIT} if the unit is invalid.
      */
@@ -413,17 +414,33 @@ public class AbstractCS extends Abstract
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT) element.
-     * Note that WKT version 1 does not define any keyword for coordinate system.
+     * Formats the inner part of this <cite>Well Known Text</cite> (WKT) CS into the given formatter.
+     * This method does <strong>not</strong> format the axes, because they shall appear outside
+     * the {@code CS[…]} element for historical reasons. Axes shall be formatted by the enclosing
+     * element (usually an {@link org.apache.sis.referencing.crs.AbstractCRS}).
+     *
+     * <blockquote><font size="-1"><b>Example:</b> Well-Known Text of a two-dimensional {@code EllipsoidalCS}
+     * having (φ,λ) axes in a unit defined by the enclosing CRS (usually degrees).
+     *
+     * {@preformat wkt
+     *   CS[ellipsoidal, 2],
+     *   Axis["latitude", north],
+     *   Axis["longitude", east]
+     * }
+     * </font></blockquote>
      *
-     * @param  formatter The formatter to use.
-     * @return The WKT element name.
+     * {@note <code>CS</code> is defined in the WKT 2 specification only.}
+     *
+     * @return {@code "CS"}.
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        for (final CoordinateSystemAxis axe : axes) {
-            formatter.append(axe);
+        final String type = ReferencingUtilities.toWKTType(CoordinateSystem.class, getInterface());
+        if (type == null) {
+            formatter.setInvalidWKT(this, null);
         }
-        return super.formatTo(formatter);
+        formatter.append(type, null);
+        formatter.append(axes.length);
+        return "CS";
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -112,10 +112,13 @@ public enum AxesConvention {
 
     /**
      * Axes are reordered for a <cite>right-handed</cite> coordinate system. Directions, ranges and units are unchanged.
-     * This enum is often used for deriving a coordinate system with the (<var>longitude</var>, <var>latitude</var>) or
-     * (<var>x</var>,<var>y</var>) axis order. While it works in many cases, note that a right-handed coordinate system
+     * In the two-dimensional case, the handedness is defined from the point of view of an observer above the plane of
+     * the system.
+     *
+     * <p>This enum is often used for deriving a coordinate system with the (<var>longitude</var>, <var>latitude</var>)
+     * or (<var>x</var>,<var>y</var>) axis order. While it works in many cases, note that a right-handed coordinate system
      * does not guarantee that longitude or <var>x</var> axis will be first in every cases. The most notable exception
-     * is the (North, West) case.
+     * is the (North, West) case.</p>
      *
      * {@note We do not provide a "<cite>longitude or <var>x</var> axis first</cite>" enumeration value because
      *        such criterion is hard to apply to inter-cardinal directions and has no meaning for map projections

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -164,9 +164,12 @@ public final class CoordinateSystems ext
         /*
          * Check for "South along 90° East", etc. directions. Note that this
          * check may perform a relatively costly parsing of axis direction name.
+         * (NOTE: the check for 'isUserDefined' is performed outside DirectionAlongMeridian for
+         * avoiding class initialization of the later in the common case where we do not need it).
          */
-        final DirectionAlongMeridian srcMeridian = DirectionAlongMeridian.parse(source);
-        final DirectionAlongMeridian tgtMeridian = DirectionAlongMeridian.parse(target);
+        final DirectionAlongMeridian srcMeridian, tgtMeridian;
+        srcMeridian = AxisDirections.isUserDefined(source) ? DirectionAlongMeridian.parse(source) : null;
+        tgtMeridian = AxisDirections.isUserDefined(target) ? DirectionAlongMeridian.parse(target) : null;
         if (srcMeridian != null && tgtMeridian != null) {
             return new Angle(srcMeridian.angle(tgtMeridian));
         }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -29,7 +29,7 @@ import org.apache.sis.measure.Units;
 
 
 /**
- * A 2- or 3-dimensional coordinate system made of straight axes (not necessarily orthogonal).
+ * A 2- or 3-dimensional coordinate system with straight axes that are not necessarily orthogonal.
  *
  * <table class="sis"><tr>
  *   <th>Used with CRS</th>
@@ -188,7 +188,7 @@ public class DefaultAffineCS extends Abs
      */
     @Override
     final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
-        if (!AxisDirections.isSpatialOrCustom(direction, true)) {
+        if (!AxisDirections.isSpatialOrUserDefined(direction, true)) {
             return INVALID_DIRECTION;
         }
         if (!Units.isLinear(unit) && !Unit.ONE.equals(unit)) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -27,7 +27,7 @@ import org.apache.sis.measure.Angle;
 
 
 /**
- * A 1-, 2-, or 3-dimensional Cartesian coordinate system made of straight orthogonal axes.
+ * A 2- or 3-dimensional Cartesian coordinate system made of straight orthogonal axes.
  * All axes shall have the same linear unit of measure.
  *
  * <table class="sis"><tr>
@@ -84,21 +84,6 @@ public class DefaultCartesianCS extends 
     }
 
     /**
-     * Constructs a one-dimensional coordinate system from a set of properties.
-     * The properties map is given unchanged to the
-     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
-     *
-     * @param properties The properties to be given to the identified object.
-     * @param axis The axis.
-     */
-    public DefaultCartesianCS(final Map<String,?>   properties,
-                              final CoordinateSystemAxis axis)
-    {
-        super(properties, new CoordinateSystemAxis[] {axis});
-        ensurePerpendicularAxis();
-    }
-
-    /**
      * Constructs a two-dimensional coordinate system from a set of properties.
      * The properties map is given unchanged to the
      * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -30,6 +30,7 @@ import javax.xml.bind.annotation.XmlRoot
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.cs.RangeMeaning;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
@@ -45,13 +46,16 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.Convention;
+import org.apache.sis.io.wkt.ElementKind;
 
 import static java.lang.Double.doubleToLongBits;
 import static java.lang.Double.NEGATIVE_INFINITY;
 import static java.lang.Double.POSITIVE_INFINITY;
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+import static org.apache.sis.util.ArgumentChecks.*;
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
-import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty;
+import static org.apache.sis.util.collection.Containers.property;
+import static org.apache.sis.internal.metadata.MetadataUtilities.canSetProperty;
 
 // Related to JDK7
 import org.apache.sis.internal.jdk7.Objects;
@@ -96,6 +100,24 @@ public class DefaultCoordinateSystemAxis
     private static final long serialVersionUID = -7883614853277827689L;
 
     /**
+     * Key for the <code>{@value}</code> property to be given to the constructor.
+     * This is used for setting the value to be returned by {@link #getMinimumValue()}.
+     */
+    public static final String MINIMUM_VALUE_KEY = "minimumValue";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the constructor.
+     * This is used for setting the value to be returned by {@link #getMaximumValue()}.
+     */
+    public static final String MAXIMUM_VALUE_KEY = "maximumValue";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the constructor.
+     * This is used for setting the value to be returned by {@link #getRangeMeaning()}.
+     */
+    public static final String RANGE_MEANING_KEY = "rangeMeaning";
+
+    /**
      * The identifier for axis of unknown name. We have to use this identifier when the axis direction changed,
      * because such change often implies a name change too (e.g. "Westing" → "Easting"), and we can not always
      * guess what the new name should be.
@@ -200,10 +222,9 @@ public class DefaultCoordinateSystemAxis
     }
 
     /**
-     * Constructs an axis from a set of properties and a given range.
-     * The properties map is given unchanged to the
-     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
-     * The following table is a reminder of main (not all) properties:
+     * Constructs an axis from a set of properties. The properties given in argument follow the same rules
+     * than for the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * Additionally, the following properties are understood by this constructor:
      *
      * <table class="sis">
      *   <tr>
@@ -212,6 +233,24 @@ public class DefaultCoordinateSystemAxis
      *     <th>Returned by</th>
      *   </tr>
      *   <tr>
+     *     <td>{@value #MINIMUM_VALUE_KEY}</td>
+     *     <td>{@link Number}</td>
+     *     <td>{@link #getMinimumValue()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value #MAXIMUM_VALUE_KEY}</td>
+     *     <td>{@link Number}</td>
+     *     <td>{@link #getMaximumValue()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value #RANGE_MEANING_KEY}</td>
+     *     <td>{@link RangeMeaning}</td>
+     *     <td>{@link #getRangeMeaning()}</td>
+     *   </tr>
+     *   <tr>
+     *     <th colspan="3" class="hsep">Defined in parent class (reminder)</th>
+     *   </tr>
+     *   <tr>
      *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
      *     <td>{@link ReferenceIdentifier} or {@link String}</td>
      *     <td>{@link #getName()}</td>
@@ -233,47 +272,13 @@ public class DefaultCoordinateSystemAxis
      *   </tr>
      * </table>
      *
-     * @param properties   The properties to be given to the identified object.
-     * @param abbreviation The {@linkplain #getAbbreviation() abbreviation} used for this coordinate system axis.
-     * @param direction    The {@linkplain #getDirection() direction} of this coordinate system axis.
-     * @param unit         The {@linkplain #getUnit() unit of measure} used for this coordinate system axis.
-     * @param minimumValue The minimum value normally allowed for this axis, or {@link Double#NEGATIVE_INFINITY} if none.
-     * @param maximumValue The maximum value normally allowed for this axis, or {@link Double#POSITIVE_INFINITY} if none.
-     * @param rangeMeaning The meaning of axis value range specified by the minimum and maximum values, or {@code null}
-     *                     if it does not apply. Shall not be null if the minimum and maximum values are not infinite.
-     */
-    public DefaultCoordinateSystemAxis(final Map<String,?> properties,
-                                       final String        abbreviation,
-                                       final AxisDirection direction,
-                                       final Unit<?>       unit,
-                                       final double        minimumValue,
-                                       final double        maximumValue,
-                                             RangeMeaning  rangeMeaning)
-    {
-        super(properties);
-        this.abbreviation = abbreviation;
-        this.direction    = direction;
-        this.unit         = unit;
-        this.minimumValue = minimumValue;
-        this.maximumValue = maximumValue;
-        ensureNonNull("abbreviation", abbreviation);
-        ensureNonNull("direction",    direction);
-        ensureNonNull("unit",         unit);
-        if (!(minimumValue < maximumValue)) { // Use '!' for catching NaN
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalRange_2, minimumValue, maximumValue));
-        }
-        if ((minimumValue != NEGATIVE_INFINITY) || (maximumValue != POSITIVE_INFINITY)) {
-            ensureNonNull("rangeMeaning", rangeMeaning);
-        } else {
-            rangeMeaning = null;
-        }
-        this.rangeMeaning = rangeMeaning;
-    }
-
-    /**
-     * Constructs an axis from a set of properties and a range inferred from the axis unit and direction.
-     * The properties map is the same than for the {@linkplain #DefaultCoordinateSystemAxis(Map, String,
-     * AxisDirection, Unit, double, double, RangeMeaning) above constructor}.
+     * Generally speaking, information provided in the {@code properties} map are considered ignorable metadata
+     * (except the axis name) while information provided as explicit arguments may have an impact on coordinate
+     * transformation results. Exceptions to this rule are the {@code minimumValue} and {@code maximumValue} in
+     * the particular case where {@code rangeMeaning} is {@link RangeMeaning#WRAPAROUND}.
+     *
+     * <p>If no minimum, maximum and range meaning are specified, then this constructor will infer them
+     * from the axis unit and direction.</p>
      *
      * @param properties   The properties to be given to the identified object.
      * @param abbreviation The {@linkplain #getAbbreviation() abbreviation} used for this coordinate system axis.
@@ -285,39 +290,53 @@ public class DefaultCoordinateSystemAxis
                                        final AxisDirection direction,
                                        final Unit<?>       unit)
     {
-        // NOTE: we would invoke this(properties, abbreviation, ...) instead if Oracle fixed
-        // RFE #4093999 ("Relax constraint on placement of this()/super() call in constructors").
         super(properties);
         this.abbreviation = abbreviation;
         this.direction    = direction;
         this.unit         = unit;
-        ensureNonNull("abbreviation", abbreviation);
-        ensureNonNull("direction",    direction);
-        ensureNonNull("unit",         unit);
-        double min = NEGATIVE_INFINITY;
-        double max = POSITIVE_INFINITY;
-        RangeMeaning r = null;
-        if (Units.isAngular(unit)) {
-            final UnitConverter fromDegrees = NonSI.DEGREE_ANGLE.getConverterTo(unit.asType(Angle.class));
-            final AxisDirection dir = AxisDirections.absolute(direction);
-            if (dir.equals(AxisDirection.NORTH)) {
-                min = fromDegrees.convert(Latitude.MIN_VALUE);
-                max = fromDegrees.convert(Latitude.MAX_VALUE);
-                r = RangeMeaning.EXACT;
-            } else if (dir.equals(AxisDirection.EAST)) {
-                min = fromDegrees.convert(Longitude.MIN_VALUE);
-                max = fromDegrees.convert(Longitude.MAX_VALUE);
-                r = RangeMeaning.WRAPAROUND; // 180°E wraps to 180°W
-            }
-            if (min > max) {
-                final double t = min;
-                min = max;
-                max = t;
-            }
-        }
-        minimumValue = min;
-        maximumValue = max;
-        rangeMeaning = r;
+        ensureNonEmpty("abbreviation", abbreviation);
+        ensureNonNull ("direction",    direction);
+        ensureNonNull ("unit",         unit);
+        Number  minimum = property(properties, MINIMUM_VALUE_KEY, Number.class);
+        Number  maximum = property(properties, MAXIMUM_VALUE_KEY, Number.class);
+        RangeMeaning rm = property(properties, RANGE_MEANING_KEY, RangeMeaning.class);
+        if (minimum == null && maximum == null && rm == null) {
+            double min = Double.NEGATIVE_INFINITY;
+            double max = Double.POSITIVE_INFINITY;
+            if (Units.isAngular(unit)) {
+                final UnitConverter fromDegrees = NonSI.DEGREE_ANGLE.getConverterTo(unit.asType(Angle.class));
+                final AxisDirection dir = AxisDirections.absolute(direction);
+                if (dir.equals(AxisDirection.NORTH)) {
+                    min = fromDegrees.convert(Latitude.MIN_VALUE);
+                    max = fromDegrees.convert(Latitude.MAX_VALUE);
+                    rm  = RangeMeaning.EXACT;
+                } else if (dir.equals(AxisDirection.EAST)) {
+                    min = fromDegrees.convert(Longitude.MIN_VALUE);
+                    max = fromDegrees.convert(Longitude.MAX_VALUE);
+                    rm  = RangeMeaning.WRAPAROUND; // 180°E wraps to 180°W
+                }
+                if (min > max) {
+                    final double t = min;
+                    min = max;
+                    max = t;
+                }
+            }
+            minimumValue = min;
+            maximumValue = max;
+        } else {
+            minimumValue = (minimum != null) ? minimum.doubleValue() : Double.NEGATIVE_INFINITY;
+            maximumValue = (maximum != null) ? maximum.doubleValue() : Double.POSITIVE_INFINITY;
+            if (!(minimumValue < maximumValue)) { // Use '!' for catching NaN
+                throw new IllegalArgumentException(Errors.getResources(properties).getString(
+                        Errors.Keys.IllegalRange_2, minimumValue, maximumValue));
+            }
+            if ((minimumValue != NEGATIVE_INFINITY) || (maximumValue != POSITIVE_INFINITY)) {
+                ensureNonNull(RANGE_MEANING_KEY, rm);
+            } else {
+                rm = null;
+            }
+        }
+        rangeMeaning = rm;
     }
 
     /**
@@ -588,6 +607,18 @@ public class DefaultCoordinateSystemAxis
 
     /**
      * Compares the specified object with this axis for equality.
+     * The strictness level is controlled by the second argument.
+     * This method compares the following properties in every cases:
+     *
+     * <ul>
+     *   <li>{@link #getName()}</li>
+     *   <li>{@link #getDirection()}</li>
+     *   <li>{@link #getUnit()}</li>
+     * </ul>
+     *
+     * In the particular case where {@link #getRangeMeaning()} is {@code WRAPAROUND}, then {@link #getMinimumValue()}
+     * and {@link #getMaximumValue()} are considered non-ignorable metadata and will be compared for every modes.
+     * All other properties are compared only for modes stricter than {@link ComparisonMode#IGNORE_METADATA}.
      *
      * @param  object The object to compare to {@code this}.
      * @param  mode {@link ComparisonMode#STRICT STRICT} for performing a strict comparison, or
@@ -686,14 +717,84 @@ public class DefaultCoordinateSystemAxis
     }
 
     /**
-     * Formats the inner part of a <cite>Well Known Text</cite> (WKT) element.
+     * Returns {@code true} if writing an axis in the given formatter should omit the axis name.
+     * From ISO 19162: For geodetic CRSs having a geocentric Cartesian coordinate system,
+     * the axis name should be omitted as it is given through the mandatory axis direction,
+     * but the axis abbreviation, respectively ‘X’, 'Y' and ‘Z’, shall be given.
+     */
+    private boolean omitName(final Formatter formatter) {
+        return AxisDirections.isGeocentric(direction) && formatter.getEnclosingElement(1) instanceof GeodeticCRS;
+    }
+
+    /**
+     * Formats this axis as a <cite>Well Known Text</cite> {@code Axis[…]} element.
+     *
+     * {@section Constraints for WKT validity}
+     * The ISO 19162 specification puts many constraints on axis names, abbreviations and directions allowed in WKT.
+     * Most of those constraints are inherited from ISO 19111 — see {@link CoordinateSystemAxis} javadoc for some of
+     * those. The current Apache SIS implementation does not verify whether this axis name and abbreviation are
+     * compliant; we assume that the user created a valid axis.
+     * The only actions (derived from ISO 19162 rules) taken by this method are:
      *
-     * @param  formatter The formatter to use.
-     * @return The WKT element name, which is {@code "AXIS"}.
+     * <ul>
+     *   <li>Replace “<cite>Geodetic latitude</cite>” and “<cite>Geodetic longitude</cite>” names (case insensitive)
+     *       by “<cite>Latitude</cite>” and “<cite>Longitude</cite>” respectively.</li>
+     * </ul>
+     *
+     * @return {@code "Axis"}.
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        formatter.append(direction);
-        return "AXIS";
+        final Convention convention = formatter.getConvention();
+        final boolean isWKT1 = convention.majorVersion() == 1;
+        final boolean isInternal = (convention == Convention.INTERNAL);
+        String name = null;
+        if (isWKT1 || isInternal || !omitName(formatter)) {
+            name = IdentifiedObjects.getName(this, formatter.getNameAuthority());
+            if (name == null) {
+                name = IdentifiedObjects.getName(this, null);
+            }
+            if (!isInternal && name != null) {
+                if (name.equalsIgnoreCase("Geodetic latitude")) {
+                    name = "Latitude"; // ISO 19162 §7.5.3(ii)
+                } else if (name.equalsIgnoreCase("Geodetic longitude")) {
+                    name = "Longitude";
+                }
+            }
+        }
+        /*
+         * ISO 19162 §7.5.3 suggests to put abbreviation in parentheses, e.g. "Easting (x)".
+         */
+        if (!isWKT1 && (name == null || !name.equals(abbreviation))) {
+            final StringBuilder buffer = new StringBuilder();
+            if (name != null) {
+                buffer.append(name).append(' ');
+            }
+            name = buffer.append('(').append(abbreviation).append(')').toString();
+        }
+        formatter.append(name, ElementKind.AXIS);
+        /*
+         * Format the axis direction, optionally followed by a MERIDIAN[…] element
+         * if the direction is of the kind "South along 90°N" for instance.
+         */
+        AxisDirection dir = direction;
+        DirectionAlongMeridian meridian = null;
+        if (!isWKT1 && AxisDirections.isUserDefined(dir)) {
+            meridian = DirectionAlongMeridian.parse(dir);
+            if (meridian != null) {
+                dir = meridian.baseDirection;
+            }
+        }
+        formatter.append(dir);
+        formatter.append(meridian);
+        /*
+         * Formats the axis unit only if the enclosing CRS element does not provide one.
+         * If the enclosing CRS provided a contextual unit, then it is assumed to apply
+         * to all axes (we do not verify).
+         */
+        if (!isWKT1 && !formatter.hasContextualUnit(1)) {
+            formatter.append(unit);
+        }
+        return "Axis";
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -164,7 +164,7 @@ public class DefaultCylindricalCS extend
      */
     @Override
     final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
-        if (!AxisDirections.isSpatialOrCustom(direction, false)) {
+        if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
         if (!Units.isLinear(unit)) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -24,6 +24,7 @@ import org.opengis.referencing.cs.Ellips
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.internal.referencing.AxisDirections;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.measure.Units;
 
 
@@ -36,9 +37,6 @@ import org.apache.sis.measure.Units;
  * </tr><tr>
  *   <td>{@linkplain org.apache.sis.referencing.crs.DefaultGeocentricCRS Geographic}</td>
  *   <td>“Geodetic latitude”, “Geodetic longitude”, “Ellipsoidal height” (if 3D)</td>
- * </tr><tr>
- *   <td>{@linkplain org.apache.sis.referencing.crs.DefaultEngineeringCRS Engineering}</td>
- *   <td>unspecified</td>
  * </tr></table>
  *
  * {@section Immutability and thread safety}
@@ -120,6 +118,13 @@ public class DefaultEllipsoidalCS extend
                                 final CoordinateSystemAxis axis1)
     {
         super(properties, axis0, axis1);
+        for (int i=0; i<2; i++) {
+            final AxisDirection direction = super.getAxis(i).getDirection();
+            if (AxisDirections.isVertical(direction)) {
+                throw new IllegalArgumentException(Errors.format(
+                        Errors.Keys.IllegalAxisDirection_2, "EllipdoicalCS (2D)", direction));
+            }
+        }
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -157,7 +157,7 @@ public class DefaultLinearCS extends Abs
      */
     @Override
     final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
-        if (!AxisDirections.isSpatialOrCustom(direction, false)) {
+        if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
         if (!Units.isLinear(unit)) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -160,7 +160,7 @@ public class DefaultPolarCS extends Abst
      */
     @Override
     final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
-        if (!AxisDirections.isSpatialOrCustom(direction, false)) {
+        if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
         if (!Units.isLinear(unit) && !Units.isAngular(unit)) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -164,7 +164,7 @@ public class DefaultSphericalCS extends 
      */
     @Override
     final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
-        if (!AxisDirections.isSpatialOrCustom(direction, false)) {
+        if (!AxisDirections.isSpatialOrUserDefined(direction, false)) {
             return INVALID_DIRECTION;
         }
         if (!Units.isAngular(unit) && !Units.isLinear(unit)) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -26,6 +26,14 @@ import org.opengis.referencing.cs.Coordi
 /**
  * A 2- or 3-dimensional coordinate system for any combination of coordinate axes not covered by other CS types.
  *
+ * <table class="sis"><tr>
+ *   <th>Used with CRS</th>
+ *   <th>Permitted axis names</th>
+ * </tr><tr>
+ *   <td>{@linkplain org.apache.sis.referencing.crs.DefaultEngineeringCRS Engineering}</td>
+ *   <td>unspecified</td>
+ * </tr></table>
+ *
  * {@section Immutability and thread safety}
  * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
  * and the {@link CoordinateSystemAxis} instances given to the constructor are also immutable. Unless otherwise

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Map;
+import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -46,9 +47,6 @@ import org.apache.sis.internal.referenci
  * </tr><tr>
  *   <td>{@linkplain org.apache.sis.referencing.crs.DefaultVerticalCRS Vertical}</td>
  *   <td>“Gravity-related height” or “Depth”</td>
- * </tr><tr>
- *   <td>{@linkplain org.apache.sis.referencing.crs.DefaultEngineeringCRS Engineering}</td>
- *   <td>unspecified</td>
  * </tr></table>
  *
  * {@section Immutability and thread safety}
@@ -166,16 +164,21 @@ public class DefaultVerticalCS extends A
      * or an {@code INVALID_*} error code otherwise. This method is invoked at construction time.
      * The current implementation accepts only temporal directions (i.e. {@link AxisDirection#UP}
      * and {@link AxisDirection#DOWN}).
-     *
-     * <p>We currently put no restriction on the unit because it may be linear, temporal (time
-     * needed for echo to travel), pressure, or dimensionless (sigma-level).</p>
      */
     @Override
-    final int validateAxis(final AxisDirection direction, final Unit<?> unit) {
+    final int validateAxis(final AxisDirection direction, Unit<?> unit) {
         if (!AxisDirection.UP.equals(AxisDirections.absolute(direction))) {
             return INVALID_DIRECTION;
         }
-        return VALID;
+        unit = unit.toSI();
+        if (unit.equals(SI.METRE)   ||  // Most usual case.
+            unit.equals(SI.PASCAL)  ||  // Height or depth estimated by the atmospheric or ocean pressure.
+            unit.equals(SI.SECOND)  ||  // Depth estimated by the time needed for an echo to travel.
+            unit.equals(Unit.ONE))      // Sigma-level (percentage from sea surface to ocean floor).
+        {
+            return VALID;
+        }
+        return INVALID_UNIT;
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -16,20 +16,28 @@
  */
 package org.apache.sis.referencing.cs;
 
-import java.io.Serializable;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.measure.unit.NonSI;
 import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.referencing.AxisDirections;
+import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.io.wkt.Formatter;
 
 
 /**
  * Parses {@linkplain AxisDirection axis direction} of the kind "<cite>South along 90 deg East</cite>".
  * Those directions are used in the EPSG database for polar stereographic projections.
  *
+ * {@section Reference meridian}
+ * This class does not know whether the meridian is relative to Greenwich or any other reference meridian.
+ * The reference meridian shall be inferred from the geodetic datum of the {@code GeographicCRS} instance
+ * that contains (through its coordinate system) the axes having those directions. This is consistent with
+ * ISO 19162 §7.5.4(iv) - WKT 2 formatting.
+ *
  * {@section Immutability and thread safety}
  * This final class is immutable and thus inherently thread-safe.
  *
@@ -38,12 +46,7 @@ import org.apache.sis.internal.referenci
  * @version 0.4
  * @module
  */
-final class DirectionAlongMeridian implements Comparable<DirectionAlongMeridian>, Serializable {
-    /**
-     * For cross-version compatibility.
-     */
-    private static final long serialVersionUID = 1602711631943838328L;
-
+final class DirectionAlongMeridian extends FormattableObject implements Comparable<DirectionAlongMeridian> {
     /**
      * A parser for EPSG axis names. Examples:
      *
@@ -94,6 +97,9 @@ final class DirectionAlongMeridian imple
 
     /**
      * Returns the direction along meridian for the specified axis direction, or {@code null} if none.
+     *
+     * <p>TIP: caller can check {@link AxisDirections#isUserDefined(AxisDirection)} before to invoke this method
+     * for avoiding {@code DirectionAlongMeridian} initialization in the common case where it is not needed.</p>
      */
     public static DirectionAlongMeridian parse(final AxisDirection direction) {
         final DirectionAlongMeridian candidate = parse(direction.name());
@@ -236,7 +242,7 @@ final class DirectionAlongMeridian imple
      */
     @Override
     public int hashCode() {
-        return Numerics.hashCode(serialVersionUID ^ (Double.doubleToLongBits(meridian) + baseDirection.hashCode()));
+        return Numerics.hashCode(Double.doubleToLongBits(meridian) + baseDirection.hashCode());
     }
 
     /**
@@ -273,4 +279,21 @@ final class DirectionAlongMeridian imple
         assert EPSG.matcher(name).matches() : name;
         return name;
     }
+
+    /**
+     * Formats this object as a <cite>Well Known Text</cite> {@code Meridian[…]} element.
+     * This element contains the meridian value and the unit of measurement.
+     * The unit is currently fixed to degrees, but this may change in any future implementation.
+     *
+     * {@note <code>Meridian</code> is defined in the WKT 2 specification only.}
+     *
+     * @param  formatter The formatter where to format the inner content of this WKT element.
+     * @return {@code "Meridian"}.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        formatter.append(meridian);
+        formatter.append(NonSI.DEGREE_ANGLE);
+        return "Meridian";
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Map;
+import java.util.HashMap;
 import java.util.Arrays;
 import javax.measure.unit.Unit;
 import javax.measure.unit.SI;
@@ -74,7 +75,8 @@ final class Normalizer implements Compar
      */
     private Normalizer(final CoordinateSystemAxis axis) {
         this.axis = axis;
-        meridian = DirectionAlongMeridian.parse(axis.getDirection());
+        final AxisDirection dir = axis.getDirection();
+        meridian = AxisDirections.isUserDefined(dir) ? DirectionAlongMeridian.parse(dir) : null;
     }
 
     /**
@@ -177,11 +179,11 @@ final class Normalizer implements Compar
                 newAbbr = "t";
             }
         }
-        final Map<String,?> properties;
+        final Map<String,Object> properties = new HashMap<String,Object>();
         if (newAbbr.equals(abbreviation)) {
-            properties = IdentifiedObjects.getProperties(axis, EXCLUDES);
+            properties.putAll(IdentifiedObjects.getProperties(axis, EXCLUDES));
         } else {
-            properties = singletonMap(NAME_KEY, DefaultCoordinateSystemAxis.UNNAMED);
+            properties.put(NAME_KEY, DefaultCoordinateSystemAxis.UNNAMED);
         }
         /*
          * Converts the axis range and build the new axis.
@@ -193,8 +195,10 @@ final class Normalizer implements Compar
             // Use IllegalStateException because the public API is an AbstractCS member method.
             throw new IllegalStateException(Errors.format(Errors.Keys.IllegalUnitFor_2, "axis", unit), e);
         }
-        return new DefaultCoordinateSystemAxis(properties, newAbbr, newDir, newUnit,
-                c.convert(axis.getMinimumValue()), c.convert(axis.getMaximumValue()), axis.getRangeMeaning());
+        properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, c.convert(axis.getMinimumValue()));
+        properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, c.convert(axis.getMaximumValue()));
+        properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, axis.getRangeMeaning());
+        return new DefaultCoordinateSystemAxis(properties, newAbbr, newDir, newUnit);
     }
 
     /**
@@ -256,8 +260,13 @@ final class Normalizer implements Compar
                     min -= offset;
                     max -= offset;
                     if (min < max) { // Paranoiac check, but also a way to filter NaN values when offset is infinite.
-                        axis = new DefaultCoordinateSystemAxis(IdentifiedObjects.getProperties(axis, EXCLUDES),
-                                axis.getAbbreviation(), axis.getDirection(), axis.getUnit(), min, max, rangeMeaning);
+                        final Map<String,Object> properties = new HashMap<String,Object>();
+                        properties.putAll(IdentifiedObjects.getProperties(axis, EXCLUDES));
+                        properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, min);
+                        properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, max);
+                        properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, rangeMeaning);
+                        axis = new DefaultCoordinateSystemAxis(properties,
+                                axis.getAbbreviation(), axis.getDirection(), axis.getUnit());
                         changed = true;
                     }
                 }



Mime
View raw message