sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1688859 - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-metadata/src/test/java/org/apache/sis/test/mock/ core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ core/sis-referencing/sr...
Date Thu, 02 Jul 2015 16:45:13 GMT
Author: desruisseaux
Date: Thu Jul  2 16:45:13 2015
New Revision: 1688859

URL: http://svn.apache.org/r1688859
Log:
Merge WKT 2 work from JDK7 branch: tests and bug fixes.

Added:
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MockProvider.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MockProvider.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/PoleRotationMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/PoleRotationMock.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/SeismicBinGridMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/SeismicBinGridMock.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TopocentricConversionMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TopocentricConversionMock.java
    sis/branches/JDK6/core/sis-referencing/src/test/resources/META-INF/
      - copied from r1688858, sis/branches/JDK7/core/sis-referencing/src/test/resources/META-INF/
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
      - copied unchanged from r1688858, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
Removed:
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/PatchedUnitFormat.java
    sis/branches/JDK6/ide-project/NetBeans/build.xml

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jul  2 16:45:13 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK7:1394913-1688689
-/sis/branches/JDK8:1584960-1688688
+/sis/branches/JDK7:1394913-1688858
+/sis/branches/JDK8:1584960-1688856
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -26,6 +26,7 @@ import java.util.Locale;
 import java.io.PrintWriter;
 import java.text.ParsePosition;
 import java.text.ParseException;
+import org.opengis.referencing.cs.CoordinateSystem;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Exceptions;
@@ -383,6 +384,30 @@ final class Element {
         return new LocalizedParseException(locale, res, args, offset);
     }
 
+    /**
+     * Returns a {@link ParseException} for an illegal coordinate system.
+     *
+     * <p>The given {@code cs} argument should never be null with Apache SIS implementation of
+     * {@link org.opengis.referencing.cs.CSFactory}, but could be null with user-supplied implementation.
+     * But it would be a {@code CSFactory} contract violation, so the user would get a {@link NullPointerException}
+     * later. For making easier to trace the cause, we throw here an exception with a similar error message.</p>
+     *
+     * @param  cs The illegal coordinate system.
+     * @return The exception to be thrown.
+     */
+    final ParseException illegalCS(final CoordinateSystem cs) {
+        final short key;
+        final String value;
+        if (cs == null) {
+            key   = Errors.Keys.NullArgument_1;   // See javadoc.
+            value = "coordinateSystem";
+        } else {
+            key   = Errors.Keys.IllegalCoordinateSystem_1;
+            value = cs.getName().getCode();
+        }
+        return new LocalizedParseException(locale, key, new String[] {value}, offset);
+    }
+
 
 
 

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -339,14 +339,14 @@ final class GeodeticObjectParser extends
             throws ParseException
     {
         CoordinateReferenceSystem crs;
-        if ((crs = parseGeodeticCRS    (FIRST, element, null )) == null &&
-            (crs = parseProjectedCRS   (FIRST, element, false)) == null &&
-            (crs = parseVerticalCRS    (FIRST, element, false)) == null &&
-            (crs = parseTimeCRS        (FIRST, element, false)) == null &&
-            (crs = parseEngineeringCRS (FIRST, element, false)) == null &&
-            (crs = parseImageCRS       (FIRST, element))        == null &&
-            (crs = parseCompoundCRS    (FIRST, element))        == null &&
-            (crs = parseFittedCS       (FIRST, element))        == null)
+        if ((crs = parseGeodeticCRS    (FIRST, element, 2, null)) == null &&
+            (crs = parseProjectedCRS   (FIRST, element, false))   == null &&
+            (crs = parseVerticalCRS    (FIRST, element, false))   == null &&
+            (crs = parseTimeCRS        (FIRST, element, false))   == null &&
+            (crs = parseEngineeringCRS (FIRST, element, false))   == null &&
+            (crs = parseImageCRS       (FIRST, element))          == null &&
+            (crs = parseCompoundCRS    (FIRST, element))          == null &&
+            (crs = parseFittedCS       (FIRST, element))          == null)
         {
             if (mandatory) {
                 throw element.missingOrUnknownComponent(WKTKeywords.GeodeticCRS);
@@ -551,6 +551,20 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Returns the given unit as a linear unit, or {@code null} if it is not linear.
+     */
+    private static Unit<Length> toLinear(final Unit<?> unit) {
+        return Units.isLinear(unit) ? unit.asType(Length.class) : null;
+    }
+
+    /**
+     * Returns the given unit as an angular unit, or {@code null} if it is not angular.
+     */
+    private static Unit<Angle> toAngular(final Unit<?> unit) {
+        return Units.isAngular(unit) ? unit.asType(Angle.class) : null;
+    }
+
+    /**
      * Parses an optional {@code "UNIT"} element of a known dimension.
      * This element has the following pattern:
      *
@@ -638,7 +652,13 @@ final class GeodeticObjectParser extends
         axisOrder.clear();
         final boolean is3D = (dimension >= 3);
         Map<String,Object> csProperties = null;
-        { // For keeping the 'element' variable local to this block, for reducing the risk of accidental reuse.
+        /*
+         * Parse the CS[<type>, <dimension>] element.  This is specific to the WKT 2 format.
+         * In principle the CS element is mandatory, but the Apache SIS parser is lenient on
+         * this aspect:  if the CS element is not present, we will compute the same defaults
+         * than what we do for WKT 1.
+         */
+        if (!isWKT1) {
             final Element element = parent.pullElement(OPTIONAL, WKTKeywords.CS);
             if (element != null) {
                 final String expected = type;
@@ -737,6 +757,7 @@ final class GeodeticObjectParser extends
                     nx = AxisNames.GEODETIC_LONGITUDE; x = "λ";
                     ny = AxisNames.GEODETIC_LATITUDE;  y = "φ";
                     if (dimension >= 3) {
+                        direction = AxisDirection.UP;
                         z    = "h";
                         nz   = AxisNames.ELLIPSOIDAL_HEIGHT;
                         unit = SI.METRE;
@@ -1123,6 +1144,19 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Returns the number of source dimensions of the given operation method, or 2 if unspecified.
+     */
+    private static int getSourceDimensions(final OperationMethod method) {
+        if (method != null) {
+            final Integer dimension = method.getSourceDimensions();
+            if (dimension != null) {
+                return dimension;
+            }
+        }
+        return 2;
+    }
+
+    /**
      * Parses a {@code "Method"} (WKT 2) element, followed by parameter values. The syntax is given by
      * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#62">WKT 2 specification §9.3</a>.
      *
@@ -1405,7 +1439,7 @@ final class GeodeticObjectParser extends
      * @return The {@code "EngineeringCRS"} element as an {@link EngineeringCRS} object.
      * @throws ParseException if the {@code "EngineeringCRS"} element can not be parsed.
      */
-    private EngineeringCRS parseEngineeringCRS(final int mode, final Element parent, final boolean isBaseCRS)
+    private SingleCRS parseEngineeringCRS(final int mode, final Element parent, final boolean isBaseCRS)
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
@@ -1416,13 +1450,43 @@ final class GeodeticObjectParser extends
         if (element == null) {
             return null;
         }
-        final boolean          isWKT1 = element.getKeywordIndex() == 2;  // Index of "Local_CS" above.
-        final String           name   = element.pullString("name");
-        final EngineeringDatum datum  = parseEngineeringDatum(MANDATORY, element, isWKT1);
-        final Unit<?>          unit   = parseUnit(element);
+        final boolean isWKT1 = element.getKeywordIndex() == 2;  // Index of "Local_CS" above.
+        final String  name   = element.pullString("name");
+        final Unit<?> unit   = parseUnit(element);
+        /*
+         * An EngineeringCRS can be either a "normal" one (with a non-null datum), or a DerivedCRS.
+         * In the later case, the datum is null and we have instead DerivingConversion element from a base CRS.
+         */
+        EngineeringDatum datum    = null;
+        SingleCRS        baseCRS  = null;
+        Conversion       fromBase = null;
+        if (!isWKT1 && !isBaseCRS) {
+            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, null, null);
+            if (fromBase != null) {
+                /*
+                 * The order of base types below is arbitrary. But no matter their type,
+                 * they must be optional except the last one which should be mandatory.
+                 * The last one determines the error message to be reported if we find none.
+                 */
+                baseCRS = parseEngineeringCRS(OPTIONAL, element, true);
+                if (baseCRS == null) {
+                    baseCRS = parseGeodeticCRS(OPTIONAL, element, getSourceDimensions(fromBase.getMethod()), WKTKeywords.ellipsoidal);
+                    if (baseCRS == null) {
+                        baseCRS = parseProjectedCRS(MANDATORY, element, true);
+                    }
+                }
+            }
+        }
+        if (baseCRS == null) {  // The most usual case.
+            datum = parseEngineeringDatum(MANDATORY, element, isWKT1);
+        }
         try {
             final CoordinateSystem cs = parseCoordinateSystem(element, null, 1, isWKT1, unit, datum);
-            return crsFactory.createEngineeringCRS(parseMetadataAndClose(element, name, datum), datum, cs);
+            final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
+            if (baseCRS != null) {
+                return crsFactory.createDerivedCRS(properties, baseCRS, fromBase, cs);
+            }
+            return crsFactory.createEngineeringCRS(properties, datum, cs);
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
@@ -1445,12 +1509,17 @@ final class GeodeticObjectParser extends
         final String     name   = element.pullString("name");
         final ImageDatum datum  = parseImageDatum(MANDATORY, element);
         final Unit<?>    unit   = parseUnit(element);
+        final CoordinateSystem cs;
         try {
-            final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, false, unit, datum);
-            return crsFactory.createImageCRS(parseMetadataAndClose(element, name, datum), datum, (CartesianCS) cs);
+            cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, false, unit, datum);
+            final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
+            if (cs instanceof CartesianCS) {
+                return crsFactory.createImageCRS(properties, datum, (CartesianCS) cs);
+            }
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
+        throw element.illegalCS(cs);
     }
 
     /**
@@ -1469,17 +1538,20 @@ final class GeodeticObjectParser extends
      *     GEOCCS["<name>", <datum>, <prime meridian>, <linear unit> {,<axis> ,<axis> ,<axis>} {,<authority>}]
      * }
      *
-     * @param  mode   {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
-     * @param  parent The parent element.
-     * @param  csType The default coordinate system type, or {@code null} if unknown.
-     *                Should be non-null only when parsing a {@link GeneralDerivedCRS#getBaseCRS()} component.
+     * @param  mode      {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  parent    The parent element.
+     * @param  dimension The minimal number of dimensions (usually 2).
+     * @param  csType    The default coordinate system type, or {@code null} if unknown.
+     *                   Should be non-null only when parsing a {@link GeneralDerivedCRS#getBaseCRS()} component.
      * @return The {@code "GeodeticCRS"} element as a {@link GeographicCRS} or {@link GeocentricCRS} object.
      * @throws ParseException if the {@code "GeodeticCRS"} element can not be parsed.
      *
      * @see org.apache.sis.referencing.crs.DefaultGeographicCRS#formatTo(Formatter)
      * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS#formatTo(Formatter)
      */
-    private SingleCRS parseGeodeticCRS(final int mode, final Element parent, String csType) throws ParseException {
+    private SingleCRS parseGeodeticCRS(final int mode, final Element parent, int dimension, String csType)
+            throws ParseException
+    {
         final Element element = parent.pullElement(mode,
                 (csType != null) ? new String[] {WKTKeywords.BaseGeodCRS,    // [0]  WKT 2 in ProjectedCRS or DerivedCRS
                                                  WKTKeywords.GeogCS}         // [1]  WKT 1 in ProjectedCRS
@@ -1493,13 +1565,11 @@ final class GeodeticObjectParser extends
         final boolean     isWKT1;
         final Unit<Angle> angularUnit;
               Unit<?>     defaultUnit;
-        final int         dimension;
         switch (element.getKeywordIndex()) {
             default: {      // WKT2 element.
                 isWKT1      = false;
                 defaultUnit = parseUnit(element);
                 angularUnit = Units.isAngular(defaultUnit) ? defaultUnit.asType(Angle.class) : NonSI.DEGREE_ANGLE;
-                dimension   = 2;
                 if (defaultUnit == null) {
                     /*
                      * A UNIT[…] is mandatory either in the CoordinateSystem as a whole (defaultUnit != null),
@@ -1539,9 +1609,9 @@ final class GeodeticObjectParser extends
         SingleCRS     baseCRS  = null;
         Conversion    fromBase = null;
         if (!isWKT1 && csType == null) {
-            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, SI.METRE, angularUnit);
+            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, toLinear(defaultUnit), angularUnit);
             if (fromBase != null) {
-                baseCRS = parseGeodeticCRS(MANDATORY, element, WKTKeywords.ellipsoidal);
+                baseCRS = parseGeodeticCRS(MANDATORY, element, getSourceDimensions(fromBase.getMethod()), WKTKeywords.ellipsoidal);
             }
         }
         if (baseCRS == null) {
@@ -1573,8 +1643,7 @@ final class GeodeticObjectParser extends
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
-        throw new LocalizedParseException(errorLocale, Errors.Keys.IllegalCoordinateSystem_1,
-                new Object[] {cs.getClass()}, element.offset);
+        throw element.illegalCS(cs);
     }
 
     /**
@@ -1593,7 +1662,7 @@ final class GeodeticObjectParser extends
      * @return The {@code "VerticalCRS"} element as a {@link VerticalCRS} object.
      * @throws ParseException if the {@code "VerticalCRS"} element can not be parsed.
      */
-    private VerticalCRS parseVerticalCRS(final int mode, final Element parent, final boolean isBaseCRS)
+    private SingleCRS parseVerticalCRS(final int mode, final Element parent, final boolean isBaseCRS)
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
@@ -1606,33 +1675,56 @@ final class GeodeticObjectParser extends
         }
         final boolean isWKT1 = element.getKeywordIndex() == 2;  // Index of "Vert_CS" above.
         final String  name   = element.pullString("name");
-        VerticalDatum datum  = parseVerticalDatum(MANDATORY, element, isWKT1);
         final Unit<?> unit   = parseUnit(element);
+        /*
+         * A VerticalCRS can be either a "normal" one (with a non-null datum), or a DerivedCRS of kind VerticalCRS.
+         * In the later case, the datum is null and we have instead DerivingConversion element from a BaseVertCRS.
+         */
+        VerticalDatum datum    = null;
+        SingleCRS     baseCRS  = null;
+        Conversion    fromBase = null;
+        if (!isWKT1 && !isBaseCRS) {
+            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, toLinear(unit), null);
+            if (fromBase != null) {
+                baseCRS = parseVerticalCRS(MANDATORY, element, true);
+            }
+        }
+        if (baseCRS == null) {  // The most usual case.
+            datum = parseVerticalDatum(MANDATORY, element, isWKT1);
+        }
+        final CoordinateSystem cs;
         try {
-            final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.vertical, 1, isWKT1, unit, datum);
-            /*
-             * The 'parseVerticalDatum(…)' method may have been unable to resolve the datum type.
-             * But sometime the axis (which was not available when we created the datum) provides
-             * more information. Verify if we can have a better type now, and if so rebuild the datum.
-             */
-            if (VerticalDatumType.OTHER_SURFACE.equals(datum.getVerticalDatumType())) {
-                final VerticalDatumType type = VerticalDatumTypes.guess(datum.getName().getCode(), datum.getAlias(), cs.getAxis(0));
-                if (!VerticalDatumType.OTHER_SURFACE.equals(type)) {
-                    datum = datumFactory.createVerticalDatum(referencing.getProperties(datum), type);
+            cs = parseCoordinateSystem(element, WKTKeywords.vertical, 1, isWKT1, unit, datum);
+            final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
+            if (cs instanceof VerticalCS) {
+                if (baseCRS != null) {
+                    return crsFactory.createDerivedCRS(properties, baseCRS, fromBase, cs);
                 }
+                /*
+                 * The 'parseVerticalDatum(…)' method may have been unable to resolve the datum type.
+                 * But sometime the axis (which was not available when we created the datum) provides
+                 * more information. Verify if we can have a better type now, and if so rebuild the datum.
+                 */
+                if (VerticalDatumType.OTHER_SURFACE.equals(datum.getVerticalDatumType())) {
+                    final VerticalDatumType type = VerticalDatumTypes.guess(datum.getName().getCode(), datum.getAlias(), cs.getAxis(0));
+                    if (!VerticalDatumType.OTHER_SURFACE.equals(type)) {
+                        datum = datumFactory.createVerticalDatum(referencing.getProperties(datum), type);
+                    }
+                }
+                verticalCRS = crsFactory.createVerticalCRS(properties, datum, (VerticalCS) cs);
+                /*
+                 * Some DefaultVerticalExtent objects may be waiting for the VerticalCRS before to complete
+                 * their construction. If this is the case, try to complete them now.
+                 */
+                if (verticalElements != null) {
+                    verticalElements = verticalElements.resolve(verticalCRS);
+                }
+                return verticalCRS;
             }
-            verticalCRS = crsFactory.createVerticalCRS(parseMetadataAndClose(element, name, datum), datum, (VerticalCS) cs);
-            /*
-             * Some DefaultVerticalExtent objects may be waiting for the VerticalCRS before to complete
-             * their construction. If this is the case, try to complete them now.
-             */
-            if (verticalElements != null) {
-                verticalElements = verticalElements.resolve(verticalCRS);
-            }
-            return verticalCRS;
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
+        throw element.illegalCS(cs);
     }
 
     /**
@@ -1644,22 +1736,45 @@ final class GeodeticObjectParser extends
      * @return The {@code "TimeCRS"} element as a {@link TemporalCRS} object.
      * @throws ParseException if the {@code "TimeCRS"} element can not be parsed.
      */
-    private TemporalCRS parseTimeCRS(final int mode, final Element parent, final boolean isBaseCRS)
+    private SingleCRS parseTimeCRS(final int mode, final Element parent, final boolean isBaseCRS)
             throws ParseException
     {
         final Element element = parent.pullElement(mode, isBaseCRS ? WKTKeywords.BaseTimeCRS : WKTKeywords.TimeCRS);
         if (element == null) {
             return null;
         }
-        final String         name     = element.pullString("name");
-        final TemporalDatum  datum    = parseTimeDatum(MANDATORY, element);
-        final Unit<Duration> timeUnit = parseScaledUnit(element, WKTKeywords.TimeUnit, SI.SECOND);
+        final String         name = element.pullString("name");
+        final Unit<Duration> unit = parseScaledUnit(element, WKTKeywords.TimeUnit, SI.SECOND);
+        /*
+         * A TemporalCRS can be either a "normal" one (with a non-null datum), or a DerivedCRS of kind TemporalCRS.
+         * In the later case, the datum is null and we have instead DerivingConversion element from a BaseTimeCRS.
+         */
+        TemporalDatum datum    = null;
+        SingleCRS     baseCRS  = null;
+        Conversion    fromBase = null;
+        if (!isBaseCRS) {
+            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, null, null);
+            if (fromBase != null) {
+                baseCRS = parseTimeCRS(MANDATORY, element, true);
+            }
+        }
+        if (baseCRS == null) {  // The most usual case.
+            datum = parseTimeDatum(MANDATORY, element);
+        }
+        final CoordinateSystem cs;
         try {
-            final CoordinateSystem cs = parseCoordinateSystem(element, WKTKeywords.temporal, 1, false, timeUnit, datum);
-            return crsFactory.createTemporalCRS(parseMetadataAndClose(element, name, datum), datum, (TimeCS) cs);
+            cs = parseCoordinateSystem(element, WKTKeywords.temporal, 1, false, unit, datum);
+            final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
+            if (cs instanceof TimeCS) {
+                if (baseCRS != null) {
+                    return crsFactory.createDerivedCRS(properties, baseCRS, fromBase, cs);
+                }
+                return crsFactory.createTemporalCRS(properties, datum, (TimeCS) cs);
+            }
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
+        throw element.illegalCS(cs);
     }
 
     /**
@@ -1693,25 +1808,43 @@ final class GeodeticObjectParser extends
         }
         final boolean   isWKT1 = element.getKeywordIndex() == 2;  // Index of "ProjCS" above.
         final String    name   = element.pullString("name");
-        final SingleCRS geoCRS = parseGeodeticCRS(MANDATORY, element, WKTKeywords.ellipsoidal);
+        final SingleCRS geoCRS = parseGeodeticCRS(MANDATORY, element, 2, WKTKeywords.ellipsoidal);
         if (!(geoCRS instanceof GeographicCRS)) {
             throw new LocalizedParseException(errorLocale, Errors.Keys.IllegalCRSType_1,
                     new Object[] {geoCRS.getClass()}, element.offset);
         }
-        final Unit<Length> linearUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
+        /*
+         * Parse the projection parameters. If a default linear unit is specified, it will apply to
+         * all parameters that do not specify explicitely a LengthUnit. If no such crs-wide unit was
+         * specified, then the default will be the unit specified in the parameter descriptor.
+         */
+        Unit<Length> linearUnit = parseScaledUnit(element, WKTKeywords.LengthUnit, SI.METRE);
         final boolean ignoreUnits = isWKT1 && usesCommonUnits;
         final Conversion conversion = parseDerivingConversion(MANDATORY, element,
                 isWKT1 ? null : WKTKeywords.Conversion, ignoreUnits ? SI.METRE : linearUnit,
                 ignoreUnits ? NonSI.DEGREE_ANGLE : geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class));
-
+        /*
+         * Parse the coordinate system. The linear unit must be specified somewhere, either explicitely in each axis
+         * or for the whole CRS with the above 'linearUnit' value. If 'linearUnit' is null, then an exception will be
+         * thrown with a message like "A LengthUnit component is missing in ProjectedCRS".
+         *
+         * However we make an exception if we are parsing a BaseProjCRS, since the coordinate system is unspecified
+         * in the WKT of base CRS. In this case only, we will default to metre.
+         */
+        if (linearUnit == null && isBaseCRS) {
+            linearUnit = SI.METRE;
+        }
         final CoordinateSystem cs;
         try {
             cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, isWKT1, linearUnit, geoCRS.getDatum());
             final Map<String,?> properties = parseMetadataAndClose(element, name, conversion);
-            return crsFactory.createProjectedCRS(properties, (GeographicCRS) geoCRS, conversion, (CartesianCS) cs);
+            if (cs instanceof CartesianCS) {
+                return crsFactory.createProjectedCRS(properties, (GeographicCRS) geoCRS, conversion, (CartesianCS) cs);
+            }
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }
+        throw element.illegalCS(cs);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -523,6 +523,7 @@ public class DefaultDerivedCRS extends A
         if (isWKT1) {
             return WKTKeywords.Fitted_CS;
         } else {
+            formatter.newLine();
             formatter.append(new FormattableObject() {     // Format inside a "DefiningConversion" element.
                 @Override protected String formatTo(final Formatter formatter) {
                     WKTUtilities.appendName(conversion, formatter, null);

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -268,7 +268,7 @@ public final strictfp class GeodeticObje
      */
     @Test
     @DependsOnMethod("testGeographicCRS")
-    public void testWithAxisSwapping() throws ParseException {
+    public void testGeographicWithLatLonAxes() throws ParseException {
         verifyGeographicCRS(1, parse(GeographicCRS.class,
                "  GEOGCS[“WGS 84”,\n" +
                "    DATUM[“World Geodetic System 1984”,\n" +
@@ -284,11 +284,11 @@ public final strictfp class GeodeticObje
      *
      * @throws ParseException if the parsing failed.
      *
-     * @see #testWithImplicitAxesInSeconds()
+     * @see #testGeographicWithImplicitAxesInSeconds()
      */
     @Test
     @DependsOnMethod("testGeographicCRS")
-    public void testWithImplicitAxes() throws ParseException {
+    public void testGeographicWithImplicitAxes() throws ParseException {
         verifyGeographicCRS(0, parse(GeographicCRS.class,
                "  GEOGCS[“WGS 84”,\n" +
                "    DATUM[“World Geodetic System 1984”,\n" +
@@ -298,6 +298,52 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests parsing geographic CRS with implicit axes in seconds instead of degrees.
+     *
+     * @throws ParseException if the parsing failed.
+     *
+     * @see #testGeographicWithImplicitAxes()
+     */
+    @Test
+    @DependsOnMethod("testGeographicWithImplicitAxes")
+    public void testGeographicWithImplicitAxesInSeconds() throws ParseException {
+        final GeographicCRS crs = parse(GeographicCRS.class,
+                "GEOGCS[“NAD83 / NFIS Seconds”," +
+                "DATUM[“North_American_Datum_1983”,\n" +
+                "SPHEROID[“GRS 1980”, 6378137, 298.257222101]],\n" +
+                "PRIMEM[“Greenwich”, 0],\n" +
+                "UNIT[“Decimal_Second”, 4.84813681109536e-06],\n" +
+                "AUTHORITY[“EPSG”, “100001”]]");
+
+        assertNameAndIdentifierEqual("NAD83 / NFIS Seconds", 100001, crs);
+
+        final GeodeticDatum datum = crs.getDatum();
+        assertNameAndIdentifierEqual("North_American_Datum_1983", 0, datum);
+        assertNameAndIdentifierEqual("Greenwich", 0, datum.getPrimeMeridian());
+
+        final Ellipsoid ellipsoid = datum.getEllipsoid();
+        assertNameAndIdentifierEqual("GRS 1980", 0, ellipsoid);
+        assertEquals("semiMajor", 6378137, ellipsoid.getSemiMajorAxis(), STRICT);
+        assertEquals("inverseFlattening", 298.257222101, ellipsoid.getInverseFlattening(), STRICT);
+
+        final EllipsoidalCS cs = crs.getCoordinateSystem();
+        final double secondsIn90 = 90*60*60;
+        CoordinateSystemAxis axis = cs.getAxis(0);
+        assertEquals("name", AxisNames.GEODETIC_LONGITUDE, axis.getName().getCode());
+        assertEquals("abbreviation", "λ",                  axis.getAbbreviation());
+        assertEquals("direction",    AxisDirection.EAST,   axis.getDirection());
+        assertEquals("minimumValue", -secondsIn90*2,       axis.getMinimumValue(), 1E-9);
+        assertEquals("maximumValue", +secondsIn90*2,       axis.getMaximumValue(), 1E-9);
+
+        axis = cs.getAxis(1);
+        assertEquals("name", AxisNames.GEODETIC_LATITUDE,  axis.getName().getCode());
+        assertEquals("abbreviation", "φ",                  axis.getAbbreviation());
+        assertEquals("direction",    AxisDirection.NORTH,  axis.getDirection());
+        assertEquals("minimumValue", -secondsIn90,         axis.getMinimumValue(), 1E-9);
+        assertEquals("maximumValue", +secondsIn90,         axis.getMaximumValue(), 1E-9);
+    }
+
+    /**
      * Tests the parsing of a geographic CRS from a WKT string with axes in wrong order according the
      * {@code ORDER} elements. The {@code ORDER} elements are defined in WKT 2 (they did not existed in WKT 1),
      * but the rest of the string is WKT 1. The SIS parser should sort the axes in the order declared
@@ -306,8 +352,8 @@ public final strictfp class GeodeticObje
      * @throws ParseException if the parsing failed.
      */
     @Test
-    @DependsOnMethod("testWithAxisSwapping")
-    public void testAxisSorting() throws ParseException {
+    @DependsOnMethod("testGeographicWithLatLonAxes")
+    public void testGeographicWithUnorderedAxes() throws ParseException {
         verifyGeographicCRS(1, parse(GeographicCRS.class,
                "  GEOGCS[“WGS 84”,\n" +
                "    DATUM[“World Geodetic System 1984”,\n" +
@@ -319,6 +365,56 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests parsing of a CRS using a prime meridian other than Greenwich. The result depends on whether
+     * the parsing is standard compliant or if the parsing use {@link Convention#WKT1_COMMON_UNITS}.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testGeographicCRS")
+    public void testGeographicWithParisMeridian() throws ParseException {
+        String wkt = "GEOGCS[“NTF (Paris)”,\n" +
+                     "  DATUM[“Nouvelle Triangulation Française (Paris)”,\n" +
+                     "    SPHEROID[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]],\n" +
+                     "    PRIMEM[“Paris”, 2.5969213, AUTHORITY[“EPSG”, “8903”]],\n" +
+                     "  UNIT[“grade”, 0.015707963267948967],\n" +
+                     "  AXIS[“Latitude”, NORTH],\n" +
+                     "  AXIS[“Longitude”, EAST]]";
+
+        GeographicCRS crs = parse(GeographicCRS.class, wkt);
+        assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
+        PrimeMeridian pm = verifyNTF(crs.getDatum(), false);
+        assertEquals("angularUnit", NonSI.GRADE, pm.getAngularUnit());
+        assertEquals("greenwichLongitude", 2.5969213, pm.getGreenwichLongitude(), STRICT);
+        EllipsoidalCS cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 2, cs.getDimension());
+        assertAxisEquals(AxisNames.GEODETIC_LATITUDE,  "φ", AxisDirection.NORTH, -100, +100, NonSI.GRADE, RangeMeaning.EXACT,      cs.getAxis(0));
+        assertAxisEquals(AxisNames.GEODETIC_LONGITUDE, "λ", AxisDirection.EAST,  -200, +200, NonSI.GRADE, RangeMeaning.WRAPAROUND, cs.getAxis(1));
+        /*
+         * Parse again using Convention.WKT1_COMMON_UNITS and ignoring AXIS[…] elements (but not the UNIT[…] element,
+         * which still apply to the axes). When using this convention, the parser does not apply the angular units to
+         * the Greenwich longitude value in PRIMEM[…] elements. Instead, the longitude is unconditionally interpreted
+         * as a value in degrees, which is why we convert "2.5969213" grade to "2.33722917" degrees in the WKT before
+         * to run the test (but we do NOT change the UNIT[…] element since the purpose of this test is to verify that
+         * those units are ignored).
+         *
+         * This is a violation of both OGC 01-009 and ISO 19162 standards, but this is what GDAL does.
+         * So we allow this interpretation in Convention.WKT1_COMMON_UNITS for compatibility reasons.
+         */
+        wkt = wkt.replace("2.5969213", "2.33722917");   // Convert unit in prime meridian.
+        newParser(Convention.WKT1_IGNORE_AXES);
+        crs = parse(GeographicCRS.class, wkt);
+        assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
+        pm = verifyNTF(crs.getDatum(), false);
+        assertEquals("angularUnit", NonSI.DEGREE_ANGLE, pm.getAngularUnit());
+        assertEquals("greenwichLongitude", 2.33722917, pm.getGreenwichLongitude(), STRICT);
+        cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 2, cs.getDimension());
+        assertAxisEquals(AxisNames.GEODETIC_LONGITUDE, "λ", AxisDirection.EAST,  -200, +200, NonSI.GRADE, RangeMeaning.WRAPAROUND, cs.getAxis(0));
+        assertAxisEquals(AxisNames.GEODETIC_LATITUDE,  "φ", AxisDirection.NORTH, -100, +100, NonSI.GRADE, RangeMeaning.EXACT,      cs.getAxis(1));
+    }
+
+    /**
      * Implementation of {@link #testGeographicCRS()} and {@link #testWithAxisSwapping()}.
      * This test expects no {@code AUTHORITY} element on any component.
      *
@@ -402,64 +498,14 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Tests parsing of a CRS using a prime meridian other than Greenwich. The result depends on whether
-     * the parsing is standard compliant or if the parsing use {@link Convention#WKT1_COMMON_UNITS}.
-     *
-     * @throws ParseException if the parsing failed.
-     */
-    @Test
-    @DependsOnMethod("testGeographicCRS")
-    public void testWithNonGreenwichMeridian() throws ParseException {
-        String wkt = "GEOGCS[“NTF (Paris)”,\n" +
-                     "  DATUM[“Nouvelle Triangulation Française (Paris)”,\n" +
-                     "    SPHEROID[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]],\n" +
-                     "    PRIMEM[“Paris”, 2.5969213, AUTHORITY[“EPSG”, “8903”]],\n" +
-                     "  UNIT[“grade”, 0.015707963267948967],\n" +
-                     "  AXIS[“Latitude”, NORTH],\n" +
-                     "  AXIS[“Longitude”, EAST]]";
-
-        GeographicCRS crs = parse(GeographicCRS.class, wkt);
-        assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
-        PrimeMeridian pm = verifyNTF(crs.getDatum(), false);
-        assertEquals("angularUnit", NonSI.GRADE, pm.getAngularUnit());
-        assertEquals("greenwichLongitude", 2.5969213, pm.getGreenwichLongitude(), STRICT);
-        EllipsoidalCS cs = crs.getCoordinateSystem();
-        assertEquals("dimension", 2, cs.getDimension());
-        assertAxisEquals(AxisNames.GEODETIC_LATITUDE,  "φ", AxisDirection.NORTH, -100, +100, NonSI.GRADE, RangeMeaning.EXACT,      cs.getAxis(0));
-        assertAxisEquals(AxisNames.GEODETIC_LONGITUDE, "λ", AxisDirection.EAST,  -200, +200, NonSI.GRADE, RangeMeaning.WRAPAROUND, cs.getAxis(1));
-        /*
-         * Parse again using Convention.WKT1_COMMON_UNITS and ignoring AXIS[…] elements (but not the UNIT[…] element,
-         * which still apply to the axes). When using this convention, the parser does not apply the angular units to
-         * the Greenwich longitude value in PRIMEM[…] elements. Instead, the longitude is unconditionally interpreted
-         * as a value in degrees, which is why we convert "2.5969213" grade to "2.33722917" degrees in the WKT before
-         * to run the test (but we do NOT change the UNIT[…] element since the purpose of this test is to verify that
-         * those units are ignored).
-         *
-         * This is a violation of both OGC 01-009 and ISO 19162 standards, but this is what GDAL does.
-         * So we allow this interpretation in Convention.WKT1_COMMON_UNITS for compatibility reasons.
-         */
-        wkt = wkt.replace("2.5969213", "2.33722917");   // Convert unit in prime meridian.
-        newParser(Convention.WKT1_IGNORE_AXES);
-        crs = parse(GeographicCRS.class, wkt);
-        assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
-        pm = verifyNTF(crs.getDatum(), false);
-        assertEquals("angularUnit", NonSI.DEGREE_ANGLE, pm.getAngularUnit());
-        assertEquals("greenwichLongitude", 2.33722917, pm.getGreenwichLongitude(), STRICT);
-        cs = crs.getCoordinateSystem();
-        assertEquals("dimension", 2, cs.getDimension());
-        assertAxisEquals(AxisNames.GEODETIC_LONGITUDE, "λ", AxisDirection.EAST,  -200, +200, NonSI.GRADE, RangeMeaning.WRAPAROUND, cs.getAxis(0));
-        assertAxisEquals(AxisNames.GEODETIC_LATITUDE,  "φ", AxisDirection.NORTH, -100, +100, NonSI.GRADE, RangeMeaning.EXACT,      cs.getAxis(1));
-    }
-
-    /**
      * Tests the parsing of a projected CRS using angular values in grades instead than degrees
      * and in lengths in kilometres instead than metres.
      *
      * @throws ParseException if the parsing failed.
      */
     @Test
-    @DependsOnMethod({"testWithNonGreenwichMeridian", "testProjectedCRS"})
-    public void testWithLessCommonUnits() throws ParseException {
+    @DependsOnMethod({"testGeographicWithParisMeridian", "testProjectedCRS"})
+    public void testProjectedWithGradUnits() throws ParseException {
         String wkt = "PROJCS[“NTF (Paris) / Lambert zone II”," +
                      "  GEOGCS[“NTF (Paris)”," +
                      "    DATUM[“Nouvelle Triangulation Française (Paris)”," +
@@ -485,7 +531,7 @@ public final strictfp class GeodeticObje
         assertEquals("latitude_of_origin",  52.0, param.doubleValue(), STRICT);
         /*
          * Parse again using Convention.WKT1_COMMON_UNITS and ignoring AXIS[…] elements.
-         * See the comment in 'testWithNonGreenwichMeridian()' method for a discussion.
+         * See the comment in 'testGeographicWithParisMeridian' method for a discussion.
          * The new aspect tested by this method is that the unit should be ignored
          * for the parameters in addition to the prime meridian.
          */
@@ -551,109 +597,6 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Tests the parsing of a compound CRS from a WKT 1 string, except the time dimension which is WKT 2.
-     *
-     * @throws ParseException if the parsing failed.
-     */
-    @Test
-    @DependsOnMethod("testGeographicCRS")
-    public void testCompoundCRS() throws ParseException {
-        final CompoundCRS crs = parse(CompoundCRS.class,
-                "COMPD_CS[“WGS 84 + height + time”,\n" +
-                "  GEOGCS[“WGS 84”,\n" +
-                "    DATUM[“World Geodetic System 1984”,\n" +
-                "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
-                "    PRIMEM[“Greenwich”, 0.0],\n" +
-                "    UNIT[“degree”, 0.017453292519943295],\n" +
-                "    AXIS[“Longitude”, EAST],\n" +
-                "    AXIS[“Latitude”, NORTH]],\n" +
-                "  VERT_CS[“Gravity-related height”,\n" +
-                "    VERT_DATUM[“Mean Sea Level”, 2005],\n" +
-                "    UNIT[“metre”, 1],\n" +
-                "    AXIS[“Gravity-related height”, UP]],\n" +
-                "  TimeCRS[“Time”,\n" +     // WKT 2
-                "    TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17T00:00:00.0Z]],\n" +
-                "    Unit[“day”, 86400],\n" +
-                "    Axis[“Time”, FUTURE]]]");
-
-        // CompoundCRS parent
-        assertNameAndIdentifierEqual("WGS 84 + height + time", 0, crs);
-        final Iterator<CoordinateReferenceSystem> components = crs.getComponents().iterator();
-
-        // GeographicCRS child
-        verifyGeographicCRS(0, (GeographicCRS) components.next());
-
-        // VerticalCRS child
-        final VerticalCRS vertCRS = (VerticalCRS) components.next();
-        assertNameAndIdentifierEqual("Gravity-related height", 0, vertCRS);
-        assertNameAndIdentifierEqual("Mean Sea Level", 0, vertCRS.getDatum());
-
-        // TemporalCRS child
-        final TemporalCRS   timeCRS   = (TemporalCRS) components.next();
-        final TemporalDatum timeDatum = timeCRS.getDatum();
-        assertNameAndIdentifierEqual("Time", 0, timeCRS);
-        assertNameAndIdentifierEqual("Modified Julian", 0, timeDatum);
-        assertEquals("epoch", new Date(-40587 * (24*60*60*1000L)), timeDatum.getOrigin());
-
-        // No more CRS.
-        assertFalse(components.hasNext());
-
-        // Axes: we verify only the CompoundCRS ones, which should include all others.
-        final CoordinateSystem cs = crs.getCoordinateSystem();
-        assertEquals("dimension", 4, cs.getDimension());
-        assertLongitudeAxisEquals(cs.getAxis(0));
-        assertLatitudeAxisEquals (cs.getAxis(1));
-        assertUnboundedAxisEquals("Gravity-related height", "H", AxisDirection.UP, SI.METRE, cs.getAxis(2));
-        assertUnboundedAxisEquals("Time", "t", AxisDirection.FUTURE, NonSI.DAY, cs.getAxis(3));
-    }
-
-    /**
-     * Tests parsing geographic CRS with implicit axes in seconds instead of degrees.
-     *
-     * @throws ParseException if the parsing failed.
-     *
-     * @see #testWithImplicitAxes()
-     */
-    @Test
-    @DependsOnMethod("testWithImplicitAxes")
-    public void testWithImplicitAxesInSeconds() throws ParseException {
-        final GeographicCRS crs = parse(GeographicCRS.class,
-                "GEOGCS[“NAD83 / NFIS Seconds”," +
-                "DATUM[“North_American_Datum_1983”,\n" +
-                "SPHEROID[“GRS 1980”, 6378137, 298.257222101]],\n" +
-                "PRIMEM[“Greenwich”, 0],\n" +
-                "UNIT[“Decimal_Second”, 4.84813681109536e-06],\n" +
-                "AUTHORITY[“EPSG”, “100001”]]");
-
-        assertNameAndIdentifierEqual("NAD83 / NFIS Seconds", 100001, crs);
-
-        final GeodeticDatum datum = crs.getDatum();
-        assertNameAndIdentifierEqual("North_American_Datum_1983", 0, datum);
-        assertNameAndIdentifierEqual("Greenwich", 0, datum.getPrimeMeridian());
-
-        final Ellipsoid ellipsoid = datum.getEllipsoid();
-        assertNameAndIdentifierEqual("GRS 1980", 0, ellipsoid);
-        assertEquals("semiMajor", 6378137, ellipsoid.getSemiMajorAxis(), STRICT);
-        assertEquals("inverseFlattening", 298.257222101, ellipsoid.getInverseFlattening(), STRICT);
-
-        final EllipsoidalCS cs = crs.getCoordinateSystem();
-        final double secondsIn90 = 90*60*60;
-        CoordinateSystemAxis axis = cs.getAxis(0);
-        assertEquals("name", AxisNames.GEODETIC_LONGITUDE, axis.getName().getCode());
-        assertEquals("abbreviation", "λ",                  axis.getAbbreviation());
-        assertEquals("direction",    AxisDirection.EAST,   axis.getDirection());
-        assertEquals("minimumValue", -secondsIn90*2,       axis.getMinimumValue(), 1E-9);
-        assertEquals("maximumValue", +secondsIn90*2,       axis.getMaximumValue(), 1E-9);
-
-        axis = cs.getAxis(1);
-        assertEquals("name", AxisNames.GEODETIC_LATITUDE,  axis.getName().getCode());
-        assertEquals("abbreviation", "φ",                  axis.getAbbreviation());
-        assertEquals("direction",    AxisDirection.NORTH,  axis.getDirection());
-        assertEquals("minimumValue", -secondsIn90,         axis.getMinimumValue(), 1E-9);
-        assertEquals("maximumValue", +secondsIn90,         axis.getMaximumValue(), 1E-9);
-    }
-
-    /**
      * Tests parsing a WKT with a missing Geographic CRS name.
      * This should be considered invalid, but happen in practice.
      *
@@ -668,7 +611,7 @@ public final strictfp class GeodeticObje
      */
     @Test
     @DependsOnMethod("testProjectedCRS")
-    public void testWithMissingName() throws ParseException {
+    public void testProjectedWithMissingName() throws ParseException {
         final ProjectedCRS crs = parse(ProjectedCRS.class,
                 "PROJCS[“FRANCE/NTF/Lambert III”," +
                 "GEOGCS[“”," + // Missing name (the purpose of this test).
@@ -718,12 +661,96 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests the parsing of an engineering CRS from a WKT 2 string.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    public void testEngineeringCRS() throws ParseException {
+        final EngineeringCRS crs = parse(EngineeringCRS.class,
+                "EngineeringCRS[“A building-centred CRS”,\n" +
+                "  EngineeringDatum[“Building reference point”],\n" +
+                "  CS[Cartesian, 3],\n" +
+                "    Axis[“x”, east],\n" +
+                "    Axis[“y”, north],\n" +
+                "    Axis[“z”, up],\n" +
+                "    Unit[“metre”, 1]]");
+
+        assertNameAndIdentifierEqual("A building-centred CRS", 0, crs);
+        assertNameAndIdentifierEqual("Building reference point", 0, crs.getDatum());
+        final CoordinateSystem cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 3, cs.getDimension());
+
+        // Axis names are arbitrary and could change in future SIS versions.
+        assertUnboundedAxisEquals("Easting",  "x", AxisDirection.EAST,  SI.METRE, cs.getAxis(0));
+        assertUnboundedAxisEquals("Northing", "y", AxisDirection.NORTH, SI.METRE, cs.getAxis(1));
+        assertUnboundedAxisEquals("z",        "z", AxisDirection.UP,    SI.METRE, cs.getAxis(2));
+    }
+
+    /**
+     * Tests the parsing of a compound CRS from a WKT 1 string, except the time dimension which is WKT 2.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testGeographicCRS")
+    public void testCompoundCRS() throws ParseException {
+        final CompoundCRS crs = parse(CompoundCRS.class,
+                "COMPD_CS[“WGS 84 + height + time”,\n" +
+                "  GEOGCS[“WGS 84”,\n" +
+                "    DATUM[“World Geodetic System 1984”,\n" +
+                "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+                "    PRIMEM[“Greenwich”, 0.0],\n" +
+                "    UNIT[“degree”, 0.017453292519943295],\n" +
+                "    AXIS[“Longitude”, EAST],\n" +
+                "    AXIS[“Latitude”, NORTH]],\n" +
+                "  VERT_CS[“Gravity-related height”,\n" +
+                "    VERT_DATUM[“Mean Sea Level”, 2005],\n" +
+                "    UNIT[“metre”, 1],\n" +
+                "    AXIS[“Gravity-related height”, UP]],\n" +
+                "  TimeCRS[“Time”,\n" +     // WKT 2
+                "    TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17T00:00:00.0Z]],\n" +
+                "    Unit[“day”, 86400],\n" +
+                "    Axis[“Time”, FUTURE]]]");
+
+        // CompoundCRS parent
+        assertNameAndIdentifierEqual("WGS 84 + height + time", 0, crs);
+        final Iterator<CoordinateReferenceSystem> components = crs.getComponents().iterator();
+
+        // GeographicCRS child
+        verifyGeographicCRS(0, (GeographicCRS) components.next());
+
+        // VerticalCRS child
+        final VerticalCRS vertCRS = (VerticalCRS) components.next();
+        assertNameAndIdentifierEqual("Gravity-related height", 0, vertCRS);
+        assertNameAndIdentifierEqual("Mean Sea Level", 0, vertCRS.getDatum());
+
+        // TemporalCRS child
+        final TemporalCRS   timeCRS   = (TemporalCRS) components.next();
+        final TemporalDatum timeDatum = timeCRS.getDatum();
+        assertNameAndIdentifierEqual("Time", 0, timeCRS);
+        assertNameAndIdentifierEqual("Modified Julian", 0, timeDatum);
+        assertEquals("epoch", new Date(-40587 * (24*60*60*1000L)), timeDatum.getOrigin());
+
+        // No more CRS.
+        assertFalse(components.hasNext());
+
+        // Axes: we verify only the CompoundCRS ones, which should include all others.
+        final CoordinateSystem cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 4, cs.getDimension());
+        assertLongitudeAxisEquals(cs.getAxis(0));
+        assertLatitudeAxisEquals (cs.getAxis(1));
+        assertUnboundedAxisEquals("Gravity-related height", "H", AxisDirection.UP, SI.METRE, cs.getAxis(2));
+        assertUnboundedAxisEquals("Time", "t", AxisDirection.FUTURE, NonSI.DAY, cs.getAxis(3));
+    }
+
+    /**
      * Tests the production of a warning messages when the WKT contains unknown elements.
      *
      * @throws ParseException if the parsing failed.
      */
     @Test
-    @DependsOnMethod("testWithImplicitAxes")
+    @DependsOnMethod("testGeographicWithImplicitAxes")
     public void testWarnings() throws ParseException {
         newParser(Convention.DEFAULT);
         final ParsePosition position = new ParsePosition(0);

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -117,6 +117,21 @@ public final strictfp class WKTFormatTes
     }
 
     /**
+     * Tests consistency between the parser and the formatter when using the WKT 2 simplified 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("testConsistencyOfWKT2")
+    public void testConsistencyOfWKT2_Simplified() throws ParseException {
+        format = new WKTFormat(null, null);
+        format.setConvention(Convention.WKT2_SIMPLIFIED);
+        parser = format;
+        testConsistency();
+    }
+
+    /**
      * Implementation of {@link #testConsistencyOfWKT1()} and variants.
      *
      * @throws ParseException if a parsing failed.

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -74,42 +74,93 @@ public class WKTParserTest extends CRSPa
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   GEODCRS[“WGS 84”,
+     *    DATUM[“World Geodetic System 1984”,
+     *      ELLIPSOID[“WGS 84”, 6378137, 298.257223563,
+     *        LENGTHUNIT[“metre”,1.0]]],
+     *    CS[ellipsoidal,3],
+     *      AXIS[“(lat)”,north,ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      AXIS[“(lon)”,east,ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      AXIS[“ellipsoidal height (h)”,up,LENGTHUNIT[“metre”,1.0]]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
     @Test
     @Override
-    public void testGeographic() throws FactoryException {
-        super.testGeographic();
+    public void testGeographic3D() throws FactoryException {
+        super.testGeographic3D();
         verifyEllipsoidalCS();
     }
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   GEODCRS[“S-95”,
+     *    DATUM[“Pulkovo 1995”,
+     *      ELLIPSOID[“Krassowsky 1940”, 6378245, 298.3,
+     *        LENGTHUNIT[“metre”,1.0]]],
+     *    CS[ellipsoidal,2],
+     *      AXIS[“latitude”,north,ORDER[1]],
+     *      AXIS[“longitude”,east,ORDER[2]],
+     *      ANGLEUNIT[“degree”,0.0174532925199433],
+     *    REMARK[“Система Геодеэических Координвт года 1995(СК-95)”]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
     @Test
     @Override
-    public void testGeographicWithRemark() throws FactoryException {
-        super.testGeographicWithRemark();
+    public void testGeographicWithUnicode() throws FactoryException {
+        super.testGeographicWithUnicode();
         verifyEllipsoidalCS();
     }
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   GEODCRS[“NAD83”,
+     *    DATUM[“North American Datum 1983”,
+     *      ELLIPSOID[“GRS 1980”, 6378137, 298.257222101, LENGTHUNIT[“metre”,1.0]]],
+     *    CS[ellipsoidal,2],
+     *      AXIS[“latitude”,north],
+     *      AXIS[“longitude”,east],
+     *      ANGLEUNIT[“degree”,0.017453292519943],
+     *    ID[“EPSG”,4269],
+     *    REMARK[“1986 realisation”]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
     @Test
     @Override
-    public void testGeographicWithId() throws FactoryException {
-        super.testGeographicWithId();
+    public void testGeographicWithIdentifier() throws FactoryException {
+        super.testGeographicWithIdentifier();
         verifyEllipsoidalCS();
     }
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   GEODCRS[“NTF (Paris)”,
+     *    DATUM[“Nouvelle Triangulation Francaise”,
+     *      ELLIPSOID[“Clarke 1880 (IGN)”, 6378249.2, 293.4660213]],
+     *    PRIMEM[“Paris”,2.5969213],
+     *    CS[ellipsoidal,2],
+     *      AXIS[“latitude”,north,ORDER[1]],
+     *      AXIS[“longitude”,east,ORDER[2]],
+     *      ANGLEUNIT[“grad”,0.015707963267949],
+     *    REMARK[“Nouvelle Triangulation Française”]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
@@ -122,6 +173,24 @@ public class WKTParserTest extends CRSPa
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   GEODETICCRS[“JGD2000”,
+     *    DATUM[“Japanese Geodetic Datum 2000”,
+     *      ELLIPSOID[“GRS 1980”, 6378137, 298.257222101]],
+     *    CS[Cartesian,3],
+     *      AXIS[“(X)”,geocentricX],
+     *      AXIS[“(Y)”,geocentricY],
+     *      AXIS[“(Z)”,geocentricZ],
+     *      LENGTHUNIT[“metre”,1.0],
+     *    SCOPE[“Geodesy, topographic mapping and cadastre”],
+     *    AREA[“Japan”],
+     *    BBOX[17.09,122.38,46.05,157.64],
+     *    TIMEEXTENT[2002-04-01,2011-10-21],
+     *    ID[“EPSG”,4946,URI[“urn:ogc:def:crs:EPSG::4946”]],
+     *    REMARK[“注:JGD2000ジオセントリックは現在JGD2011に代わりました。”]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
@@ -143,11 +212,39 @@ public class WKTParserTest extends CRSPa
     @Test
     @Override
     @Ignore("Lambert Azimuthal Equal Area projection method not yet implemented.")
-    public void testProjected() throws FactoryException {
+    public void testProjectedYX() throws FactoryException {
     }
 
     /**
      * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   PROJCRS[“NAD27 / Texas South Central”,
+     *    BASEGEODCRS[“NAD27”,
+     *      DATUM[“North American Datum 1927”,
+     *        ELLIPSOID[“Clarke 1866”, 20925832.164, 294.97869821,
+     *          LENGTHUNIT[“US survey foot”,0.304800609601219]]]],
+     *    CONVERSION[“Texas South Central SPCS27”,
+     *      METHOD[“Lambert Conic Conformal (2SP)”,ID[“EPSG”,9802]],
+     *      PARAMETER[“Latitude of false origin”,27.83333333333333,
+     *        ANGLEUNIT[“degree”,0.0174532925199433],ID[“EPSG”,8821]],
+     *      PARAMETER[“Longitude of false origin”,-99.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433],ID[“EPSG”,8822]],
+     *      PARAMETER[“Latitude of 1st standard parallel”,28.383333333333,
+     *        ANGLEUNIT[“degree”,0.0174532925199433],ID[“EPSG”,8823]],
+     *      PARAMETER[“Latitude of 2nd standard parallel”,30.283333333333,
+     *        ANGLEUNIT[“degree”,0.0174532925199433],ID[“EPSG”,8824]],
+     *      PARAMETER[“Easting at false origin”,2000000.0,
+     *        LENGTHUNIT[“US survey foot”,0.304800609601219],ID[“EPSG”,8826]],
+     *      PARAMETER[“Northing at false origin”,0.0,
+     *        LENGTHUNIT[“US survey foot”,0.304800609601219],ID[“EPSG”,8827]]],
+     *    CS[Cartesian,2],
+     *      AXIS[“(x)”,east],
+     *      AXIS[“(y)”,north],
+     *      LENGTHUNIT[“US survey foot”,0.304800609601219],
+     *    REMARK[“Fundamental point: Meade’s Ranch KS, latitude 39°13'26.686"N, longitude 98°32'30.506"W.”]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
@@ -173,6 +270,14 @@ public class WKTParserTest extends CRSPa
 
     /**
      * Completes the GeoAPI tests with a check of axis name and vertical datum type.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   VERTCRS[“NAVD88”,
+     *    VDATUM[“North American Vertical Datum 1988”],
+     *    CS[vertical,1],
+     *      AXIS[“gravity-related height (H)”,up],LENGTHUNIT[“metre”,1.0]]
+     * }
      *
      * @throws FactoryException if an error occurred during the WKT parsing.
      */
@@ -184,4 +289,256 @@ public class WKTParserTest extends CRSPa
         assertEquals("name", AxisNames.GRAVITY_RELATED_HEIGHT, cs.getAxis(0).getName().getCode());
         assertEquals("datumType", VerticalDatumType.GEOIDAL, ((VerticalCRS) object).getDatum().getVerticalDatumType());
     }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis name.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   TIMECRS[“GPS Time”,
+     *     TDATUM[“Time origin”,TIMEORIGIN[1980-01-01T00:00:00.0Z]],
+     *     CS[temporal,1],AXIS[“time”,future],TIMEUNIT[“day”,86400.0]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testTemporal() throws FactoryException {
+        super.testTemporal();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", AxisNames.TIME, cs.getAxis(0).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   ENGINEERINGCRS[“Astra Minas Grid”,
+     *    ENGINEERINGDATUM[“Astra Minas”],
+     *    CS[Cartesian,2],
+     *      AXIS[“northing (X)”,north,ORDER[1]],
+     *      AXIS[“westing (Y)”,west,ORDER[2]],
+     *      LENGTHUNIT[“metre”,1.0],
+     *    ID[“EPSG”,5800]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testEngineering() throws FactoryException {
+        super.testEngineering();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", AxisNames.NORTHING, cs.getAxis(0).getName().getCode());
+        assertEquals("name", AxisNames.WESTING,  cs.getAxis(1).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   ENGCRS[“A construction site CRS”,
+     *    EDATUM[“P1”,ANCHOR[“Peg in south corner”]],
+     *    CS[Cartesian,2],
+     *      AXIS[“site east”,southWest,ORDER[1]],
+     *      AXIS[“site north”,southEast,ORDER[2]],
+     *      LENGTHUNIT[“metre”,1.0],
+     *    TIMEEXTENT[“date/time t1”,“date/time t2”]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testEngineeringRotated() throws FactoryException {
+        super.testEngineeringRotated();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", "site east",  cs.getAxis(0).getName().getCode());
+        assertEquals("name", "site north", cs.getAxis(1).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *   ENGCRS[“A ship-centred CRS”,
+     *    EDATUM[“Ship reference point”,ANCHOR[“Centre of buoyancy”]],
+     *    CS[Cartesian,3],
+     *      AXIS[“(x)”,forward],
+     *      AXIS[“(y)”,starboard],
+     *      AXIS[“(z)”,down],
+     *      LENGTHUNIT[“metre”,1.0]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testEngineeringForShip() throws FactoryException {
+        super.testEngineeringForShip();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        /*
+         * In this case we had no axis names, so Apache SIS reused the abbreviations.
+         * This could change in any future SIS version if we update Transliterator.
+         */
+        assertEquals("name", "x", cs.getAxis(0).getName().getCode());
+        assertEquals("name", "y", cs.getAxis(1).getName().getCode());
+        assertEquals("name", "z", cs.getAxis(2).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *  GEODCRS[“ETRS89 Lambert Azimuthal Equal Area CRS”,
+     *    BASEGEODCRS[“WGS 84”,
+     *      DATUM[“WGS 84”,
+     *        ELLIPSOID[“WGS 84”,6378137,298.2572236,LENGTHUNIT[“metre”,1.0]]]],
+     *    DERIVINGCONVERSION[“Atlantic pole”,
+     *      METHOD[“Pole rotation”,ID[“Authority”,1234]],
+     *      PARAMETER[“Latitude of rotated pole”,52.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      PARAMETER[“Longitude of rotated pole”,-30.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      PARAMETER[“Axis rotation”,-25.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433]]],
+     *    CS[ellipsoidal,2],
+     *      AXIS[“latitude”,north,ORDER[1]],
+     *      AXIS[“longitude”,east,ORDER[2]],
+     *      ANGLEUNIT[“degree”,0.0174532925199433]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testDerivedGeodetic() throws FactoryException {
+        super.testDerivedGeodetic();
+        verifyEllipsoidalCS();
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *  ENGCRS[“Topocentric example A”,
+     *    BASEGEODCRS[“WGS 84”,
+     *      DATUM[“WGS 84”,
+     *        ELLIPSOID[“WGS 84”, 6378137, 298.2572236, LENGTHUNIT[“metre”,1.0]]]],
+     *    DERIVINGCONVERSION[“Topocentric example A”,
+     *      METHOD[“Geographic/topocentric conversions”,ID[“EPSG”,9837]],
+     *      PARAMETER[“Latitude of topocentric origin”,55.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      PARAMETER[“Longitude of topocentric origin”,5.0,
+     *        ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      PARAMETER[“Ellipsoidal height of topocentric origin”,0.0,
+     *        LENGTHUNIT[“metre”,1.0]]],
+     *    CS[Cartesian,3],
+     *      AXIS[“Topocentric East (U)”,east,ORDER[1]],
+     *      AXIS[“Topocentric North (V)”,north,ORDER[2]],
+     *      AXIS[“Topocentric height (W)”,up,ORDER[3]],
+     *      LENGTHUNIT[“metre”,1.0]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testDerivedEngineeringFromGeodetic() throws FactoryException {
+        super.testDerivedEngineeringFromGeodetic();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", "Topocentric East",   cs.getAxis(0).getName().getCode());
+        assertEquals("name", "Topocentric North",  cs.getAxis(1).getName().getCode());
+        assertEquals("name", "Topocentric height", cs.getAxis(2).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testDerivedEngineeringFromProjected() throws FactoryException {
+        super.testDerivedEngineeringFromProjected();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        /*
+         * In this case we had no axis names, so Apache SIS reused the abbreviations.
+         * This could change in any future SIS version if we update Transliterator.
+         */
+        assertEquals("name", "I", cs.getAxis(0).getName().getCode());
+        assertEquals("name", "J", cs.getAxis(1).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *  COMPOUNDCRS[“NAD83 + NAVD88”,
+     *    GEODCRS[“NAD83”,
+     *      DATUM[“North American Datum 1983”,
+     *        ELLIPSOID[“GRS 1980”,6378137,298.257222101,
+     *          LENGTHUNIT[“metre”,1.0]]],
+     *        PRIMEMERIDIAN[“Greenwich”,0],
+     *      CS[ellipsoidal,2],
+     *        AXIS[“latitude”,north,ORDER[1]],
+     *        AXIS[“longitude”,east,ORDER[2]],
+     *        ANGLEUNIT[“degree”,0.0174532925199433]],
+     *      VERTCRS[“NAVD88”,
+     *        VDATUM[“North American Vertical Datum 1983”],
+     *        CS[vertical,1],
+     *          AXIS[“gravity-related height (H)”,up],
+     *          LENGTHUNIT[“metre”,1]]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testCompoundWithVertical() throws FactoryException {
+        super.testCompoundWithVertical();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", AxisNames.GEODETIC_LATITUDE,      cs.getAxis(0).getName().getCode());
+        assertEquals("name", AxisNames.GEODETIC_LONGITUDE,     cs.getAxis(1).getName().getCode());
+        assertEquals("name", AxisNames.GRAVITY_RELATED_HEIGHT, cs.getAxis(2).getName().getCode());
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     * The WKT parsed by this test is (except for quote characters):
+     *
+     * {@preformat wkt
+     *  COMPOUNDCRS[“GPS position and time”,
+     *     GEODCRS[“WGS 84”,
+     *       DATUM[“World Geodetic System 1984”,
+     *         ELLIPSOID[“WGS 84”,6378137,298.257223563]],
+     *       CS[ellipsoidal,2],
+     *         AXIS[“(lat)”,north,ORDER[1]],
+     *         AXIS[“(lon)”,east,ORDER[2]],
+     *         ANGLEUNIT[“degree”,0.0174532925199433]],
+     *     TIMECRS[“GPS Time”,
+     *       TIMEDATUM[“Time origin”,TIMEORIGIN[1980-01-01]],
+     *       CS[temporal,1],
+     *         AXIS[“time (T)”,future],
+     *         TIMEUNIT[“day”,86400]]]
+     * }
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testCompoundWithTime() throws FactoryException {
+        super.testCompoundWithTime();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals("name", AxisNames.GEODETIC_LATITUDE,  cs.getAxis(0).getName().getCode());
+        assertEquals("name", AxisNames.GEODETIC_LONGITUDE, cs.getAxis(1).getName().getCode());
+        assertEquals("name", AxisNames.TIME,               cs.getAxis(2).getName().getCode());
+    }
 }

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/PatchedUnitFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/PatchedUnitFormat.java?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/PatchedUnitFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/PatchedUnitFormat.java [UTF-8] Thu Jul  2 16:45:13 2015
@@ -174,6 +174,8 @@ public final class PatchedUnitFormat ext
             return toAppendTo.append("degree");
         } else if (SI.METRE.equals(unit)) {
             return toAppendTo.append(isLocaleUS ? "meter" : "metre");
+        } else if (NonSI.FOOT_SURVEY_US.equals(unit)) {
+            return toAppendTo.append("US survey foot");
         } else if (Units.PPM.equals(unit)) {
             return toAppendTo.append("parts per million");
         }

Modified: sis/branches/JDK6/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/ide-project/NetBeans/build.xml?rev=1688859&r1=1688858&r2=1688859&view=diff
==============================================================================
--- sis/branches/JDK6/ide-project/NetBeans/build.xml (original)
+++ sis/branches/JDK6/ide-project/NetBeans/build.xml Thu Jul  2 16:45:13 2015
@@ -109,6 +109,7 @@
     <concat destfile="${build.classes.dir}/META-INF/services/org.opengis.referencing.operation.OperationMethod" encoding="UTF-8" fixlastline="yes">
       <fileset dir="${project.root}">
         <include name="*/*/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod"/>
+        <include name="*/*/src/test/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod"/>
       </fileset>
     </concat>
 



Mime
View raw message