sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1772421 - in /sis/branches/JDK8/storage/sis-geotiff/src: main/java/org/apache/sis/storage/geotiff/ test/java/org/apache/sis/storage/geotiff/ test/java/org/apache/sis/test/suite/
Date Sat, 03 Dec 2016 00:16:38 GMT
Author: desruisseaux
Date: Sat Dec  3 00:16:38 2016
New Revision: 1772421

URL: http://svn.apache.org/viewvc?rev=1772421&view=rev
Log:
CRSBuilder now parse the prime meridian, ellipsoid and datum names encoded in the geographic CRS name.
The GeoTIFF specification does not mention that, but we see this practice in some GeoTIFF files.

Added:
    sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java   (with props)
Modified:
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
    sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoIdentifiers.java
    sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -53,6 +53,7 @@ import org.opengis.referencing.NoSuchAut
 import org.opengis.util.FactoryException;
 
 import org.apache.sis.internal.geotiff.Resources;
+import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.internal.referencing.NilReferencingObject;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.storage.MetadataBuilder;
@@ -72,6 +73,7 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
 import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 import org.apache.sis.io.TableAppender;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.Debug;
 
@@ -134,6 +136,42 @@ final class CRSBuilder {
     private static final int ENTRY_LENGTH = 4;
 
     /**
+     * Index where to store the name of the geodetic CRS, the datum, the ellipsoid and the prime meridian.
+     * The GeoTIFF specification has only one key, {@link GeoKeys#GeogCitation}, for the geographic CRS and
+     * its components. But some GeoTIFF files encode the names of all components in the value associated to
+     * that key, as in the following example:
+     *
+     * {@preformat text
+     *   GCS Name = wgs84|Datum = unknown|Ellipsoid = WGS_1984|Primem = Greenwich|
+     * }
+     *
+     * In such case, we will split the name into the components names to be stored in an array at indices
+     * given by {@code GCRS}, {@code DATUM}, {@code ELLIPSOID} and {@code PRIMEM}.
+     */
+    static final int PRIMEM = 0, ELLIPSOID = 1, DATUM = 2, GCRS = 3;
+    // PRIMEM must be first and GCRS must be last.
+
+    /**
+     * Keys that may be used in the value associated to {@link GeoKeys#GeogCitation}.
+     * For each element in this array at index {@code i}, the {@code i/2} value is equal to the
+     * {@code DATUM}, {@code ELLIPSOID} or {@code PRIMEM} constant for the corresponding type.
+     */
+    private static final String[] NAME_KEYS = {
+        // WKT 1               WKT 2
+        WKTKeywords.PrimeM,    WKTKeywords.PrimeMeridian,
+        WKTKeywords.Spheroid,  WKTKeywords.Ellipsoid,
+        WKTKeywords.Datum,     WKTKeywords.GeodeticDatum
+    };
+
+    /**
+     * Minimal length that a key in a name must have before we compare them to the {@link #NAME_KEYS}.
+     * For example a value of 5 means that {@link #parseName(String)} will accept {@code "Ellip"},
+     * {@code "Ellips"}, {@code "Ellipso"} and {@code "Ellipsoi"} as if they were {@code "Ellipsoid"}.
+     * This length shall not be greater than the length of the shortest string in {@link #NAME_KEYS}.
+     */
+    private static final int MIN_KEY_LENGTH = 5;
+
+    /**
      * The reader for which we will create coordinate reference systems.
      * This is used for reporting warnings.
      */
@@ -400,7 +438,8 @@ final class CRSBuilder {
     }
 
     /**
-     * Reports a warning about missing value for the given key.
+     * Reports a warning about missing value for the given key. The key name is opportunistically returned for
+     * building the {@link NoSuchElementException} message, but it is not the main purpose of this method.
      */
     private String missingValue(final short key) {
         final String name = GeoKeys.name(key);
@@ -421,10 +460,10 @@ final class CRSBuilder {
      * in which case we expect the given value to be equal to the value fetched from the EPSG database.
      * If the values do not match, a warning is reported and the caller should use the EPSG value.
      *
-     * @param epsg      the EPSG object, to be used for formatting the warning in case of mismatched values.
-     * @param expected  the expected value for an object identified by the {@code epsg} code.
-     * @param key       the GeoTIFF key of the user-defined value to compare with the expected one.
-     * @param unit      the unit of measurement for {@code expected} and {@code actual}, or {@code null} if none.
+     * @param  epsg      the EPSG object, to be used for formatting the warning in case of mismatched values.
+     * @param  expected  the expected value for an object identified by the {@code epsg} code.
+     * @param  key       the GeoTIFF key of the user-defined value to compare with the expected one.
+     * @param  unit      the unit of measurement for {@code expected} and {@code actual}, or {@code null} if none.
      */
     private void verify(final IdentifiedObject epsg, final double expected, final short key, final Unit<?> unit) {
         final double actual = getAsDouble(key);         // May be NaN.
@@ -447,8 +486,8 @@ final class CRSBuilder {
      * there is no need to specify the EPSG codes of the components, but the file still supply
      * those EPSG codes. If the values do not match, a warning is reported.
      *
-     * @param epsg  the EPSG object.
-     * @param key   the GeoTIFF key for the EPSG code of the given {@code epsg} object.
+     * @param  epsg  the EPSG object.
+     * @param  key   the GeoTIFF key for the EPSG code of the given {@code epsg} object.
      */
     private void verifyIdentifier(final IdentifiedObject epsg, final short key) {
         final int code = getAsInteger(key);
@@ -654,6 +693,19 @@ final class CRSBuilder {
      */
     final void complete(final MetadataBuilder metadata) {
         /*
+         * ASCII reference to published documentation on the overall configuration of the GeoTIFF file.
+         * Checked first because this code is unlikely to throw an exception, while other parsings may
+         * interrupt this method with an exception.
+         */
+        final String title = getAsString(GeoKeys.Citation);
+        if (title != null) {
+            if (!metadata.hasTitle()) {
+                metadata.addTitle(title);
+            } else {
+                metadata.setGridToCRS(title);
+            }
+        }
+        /*
          * Whether the pixel value is thought of as filling the cell area or is considered as point measurements at
          * the vertices of the grid (not in the interior of a cell).  This is determined by the value associated to
          * GeoKeys.RasterType, which can be GeoCodes.RasterPixelIsArea or GeoCodes.RasterPixelIsPoint.
@@ -669,17 +721,6 @@ final class CRSBuilder {
         }
         metadata.setCellGeometry(cg);
         metadata.setPointInPixel(po);
-        /*
-         * ASCII reference to published documentation on the overall configuration of the GeoTIFF file.
-         */
-        final String title = getAsString(GeoKeys.Citation);
-        if (title != null) {
-            if (!metadata.hasTitle()) {
-                metadata.addTitle(title);
-            } else {
-                metadata.setGridToCRS(title);
-            }
-        }
     }
 
 
@@ -774,35 +815,36 @@ final class CRSBuilder {
      * The GeoTIFF values used by this method are:
      *
      * <ul>
-     *   <li>A code given by {@link GeoKeys#GeogPrimeMeridian}.</li>
+     *   <li>A code given by {@link GeoKeys#PrimeMeridian}.</li>
      *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
-     *     <li>a prime meridian value given by {@link GeoKeys#GeogPrimeMeridianLong}.</li>
+     *     <li>a prime meridian value given by {@link GeoKeys#PrimeMeridianLong}.</li>
      *   </ul></li>
      * </ul>
      *
      * If no prime-meridian is defined, then the default is Greenwich as per GeoTIFF specification.
      *
+     * @param  names the component names to use if the prime meridian is user-defined.
      * @param  unit  the angular unit of the longitude value relative to Greenwich.
      * @return a prime meridian created from the given {@link Unit} and the above-cited GeoTIFF keys.
      * @throws NumberFormatException if a numeric value was stored as a string and can not be parsed.
      * @throws FactoryException if an error occurred during objects creation with the factories.
      */
-    private PrimeMeridian createPrimeMeridian(final Unit<Angle> unit) throws FactoryException {
-        final int epsg = getAsInteger(GeoKeys.GeogPrimeMeridian);
+    private PrimeMeridian createPrimeMeridian(final String[] names, final Unit<Angle> unit) throws FactoryException {
+        final int epsg = getAsInteger(GeoKeys.PrimeMeridian);
         switch (epsg) {
             case GeoCodes.undefined: break;         // If not specified, default to Greenwich.
             case GeoCodes.userDefined: {
-                final double longitude = getAsDouble(GeoKeys.GeogPrimeMeridianLong);
+                final double longitude = getAsDouble(GeoKeys.PrimeMeridianLong);
                 if (Double.isNaN(longitude)) {
-                    missingValue(GeoKeys.GeogPrimeMeridianLong);
+                    missingValue(GeoKeys.PrimeMeridianLong);
                 } else if (longitude != 0) {
                     /*
-                     * If the prime meridian is not Greenwich, create that meridian without name.
-                     * We do not use the name given by GeoKeys.GeogCitation because that name is
-                     * for the CRS (e.g. "WGS84") while the prime meridian names are very different
-                     * (e.g. "Paris", "Madrid", etc).
+                     * If the prime meridian is not Greenwich, create that meridian but do not use the
+                     * GeoKeys.GeogCitation value (unless it had a sub-element for the prime meridian).
+                     * This is because the citation value is for the CRS (e.g. "WGS84") while the prime
+                     * meridian names are very different (e.g. "Paris", "Madrid", etc).
                      */
-                    return objectFactory().createPrimeMeridian(properties(null), longitude, unit);
+                    return objectFactory().createPrimeMeridian(properties(names[PRIMEM]), longitude, unit);
                 }
                 break;              // Default to Greenwich.
             }
@@ -829,7 +871,7 @@ final class CRSBuilder {
      * @param  unit  the unit of measurement declared in the GeoTIFF file.
      */
     private void verify(final PrimeMeridian pm, final Unit<Angle> unit) {
-        verify(pm, ReferencingUtilities.getGreenwichLongitude(pm, unit), GeoKeys.GeogPrimeMeridianLong, unit);
+        verify(pm, ReferencingUtilities.getGreenwichLongitude(pm, unit), GeoKeys.PrimeMeridianLong, unit);
     }
 
     /**
@@ -837,38 +879,38 @@ final class CRSBuilder {
      * The GeoTIFF values used by this method are:
      *
      * <ul>
-     *   <li>A code given by {@link GeoKeys#GeogEllipsoid} tag.</li>
+     *   <li>A code given by {@link GeoKeys#Ellipsoid} tag.</li>
      *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
      *     <li>a name given by {@link GeoKeys#GeogCitation},</li>
-     *     <li>a semi major axis value given by {@link GeoKeys#GeogSemiMajorAxis},</li>
+     *     <li>a semi major axis value given by {@link GeoKeys#SemiMajorAxis},</li>
      *     <li>one of:<ul>
-     *       <li>an inverse flattening factor given by {@link GeoKeys#GeogInvFlattening},</li>
-     *       <li>or a semi major axis value given by {@link GeoKeys#GeogSemiMinorAxis}.</li>
+     *       <li>an inverse flattening factor given by {@link GeoKeys#InvFlattening},</li>
+     *       <li>or a semi major axis value given by {@link GeoKeys#SemiMinorAxis}.</li>
      *     </ul></li>
      *   </ul></li>
      * </ul>
      *
-     * @param  name  the name to use if the ellipsoid is user-defined, or {@code null} if unnamed.
+     * @param  names the component names to use if the ellipsoid is user-defined.
      * @param  unit  the linear unit of the semi-axis lengths.
      * @return an ellipsoid created from the given {@link Unit} and the above-cited GeoTIFF keys.
      * @throws NoSuchElementException if a mandatory value is missing.
      * @throws NumberFormatException if a numeric value was stored as a string and can not be parsed.
      * @throws FactoryException if an error occurred during objects creation with the factories.
      */
-    private Ellipsoid createEllipsoid(final String name, final Unit<Length> unit) throws FactoryException {
-        final int epsg = getAsInteger(GeoKeys.GeogEllipsoid);
+    private Ellipsoid createEllipsoid(final String[] names, final Unit<Length> unit) throws FactoryException {
+        final int epsg = getAsInteger(GeoKeys.Ellipsoid);
         switch (epsg) {
             case GeoCodes.undefined: {
-                throw new NoSuchElementException(missingValue(GeoKeys.GeogGeodeticDatum));
+                throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
                 /*
                  * Try to build ellipsoid from others parameters. Those parameters are the
                  * semi-major axis and either semi-minor axis or inverse flattening factor.
                  */
-                final Map<String,?> properties = properties(name);
-                final double semiMajor = getMandatoryDouble(GeoKeys.GeogSemiMajorAxis);
-                double inverseFlattening = getAsDouble(GeoKeys.GeogInvFlattening);
+                final Map<String,?> properties = properties(getOrDefault(names, ELLIPSOID));
+                final double semiMajor = getMandatoryDouble(GeoKeys.SemiMajorAxis);
+                double inverseFlattening = getAsDouble(GeoKeys.InvFlattening);
                 final Ellipsoid ellipsoid;
                 if (!Double.isNaN(inverseFlattening)) {
                     ellipsoid = objectFactory().createFlattenedSphere(properties, semiMajor, inverseFlattening, unit);
@@ -877,7 +919,7 @@ final class CRSBuilder {
                      * If the inverse flattening factory was not defined, fallback on semi-major axis length.
                      * This is a less common way to define ellipsoid (the most common way uses flattening).
                      */
-                    final double semiMinor = getMandatoryDouble(GeoKeys.GeogSemiMinorAxis);
+                    final double semiMinor = getMandatoryDouble(GeoKeys.SemiMinorAxis);
                     ellipsoid = objectFactory().createEllipsoid(properties, semiMajor, semiMinor, unit);
                 }
                 lastName = ellipsoid.getName();
@@ -906,9 +948,9 @@ final class CRSBuilder {
      */
     private void verify(final Ellipsoid ellipsoid, final Unit<Length> unit) {
         final UnitConverter uc = ellipsoid.getAxisUnit().getConverterTo(unit);
-        verify(ellipsoid, uc.convert(ellipsoid.getSemiMajorAxis()), GeoKeys.GeogSemiMajorAxis, unit);
-        verify(ellipsoid, uc.convert(ellipsoid.getSemiMinorAxis()), GeoKeys.GeogSemiMinorAxis, unit);
-        verify(ellipsoid, ellipsoid.getInverseFlattening(),         GeoKeys.GeogInvFlattening, null);
+        verify(ellipsoid, uc.convert(ellipsoid.getSemiMajorAxis()), GeoKeys.SemiMajorAxis, unit);
+        verify(ellipsoid, uc.convert(ellipsoid.getSemiMinorAxis()), GeoKeys.SemiMinorAxis, unit);
+        verify(ellipsoid, ellipsoid.getInverseFlattening(),         GeoKeys.InvFlattening, null);
     }
 
     /**
@@ -916,7 +958,7 @@ final class CRSBuilder {
      * The GeoTIFF values used by this method are:
      *
      * <ul>
-     *   <li>A code given by {@link GeoKeys#GeogGeodeticDatum}.</li>
+     *   <li>A code given by {@link GeoKeys#GeodeticDatum}.</li>
      *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
      *     <li>a name given by {@link GeoKeys#GeogCitation},</li>
      *     <li>all values required by {@link #createPrimeMeridian(Unit)} (optional),</li>
@@ -924,7 +966,7 @@ final class CRSBuilder {
      *   </ul></li>
      * </ul>
      *
-     * @param  name         the name to use if the geodetic datum is user-defined, or {@code null} if unnamed.
+     * @param  names        the component names to use if the geodetic datum is user-defined.
      * @param  angularUnit  the angular unit of the longitude value relative to Greenwich.
      * @param  linearUnit   the linear unit of the ellipsoid semi-axis lengths.
      * @throws NoSuchElementException if a mandatory value is missing.
@@ -935,13 +977,13 @@ final class CRSBuilder {
      * @see #createPrimeMeridian(Unit)
      * @see #createEllipsoid(Unit)
      */
-    private GeodeticDatum createGeodeticDatum(String name, final Unit<Angle> angularUnit, final Unit<Length> linearUnit)
+    private GeodeticDatum createGeodeticDatum(final String[] names, final Unit<Angle> angularUnit, final Unit<Length> linearUnit)
             throws FactoryException
     {
-        final int epsg = getAsInteger(GeoKeys.GeogGeodeticDatum);
+        final int epsg = getAsInteger(GeoKeys.GeodeticDatum);
         switch (epsg) {
             case GeoCodes.undefined: {
-                throw new NoSuchElementException(missingValue(GeoKeys.GeogGeodeticDatum));
+                throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
                 /*
@@ -953,8 +995,9 @@ final class CRSBuilder {
                  * CommonCRS. We use the CRS name given in the GeoTIFF file for that purpose, exploiting the
                  * fact that it is often a name that can be mapped to a CommonCRS name like "WGS84".
                  */
-                final Ellipsoid     ellipsoid = createEllipsoid(name, linearUnit);
-                final PrimeMeridian meridian  = createPrimeMeridian(angularUnit);
+                String              name      = getOrDefault(names, DATUM);
+                final Ellipsoid     ellipsoid = createEllipsoid(names, linearUnit);
+                final PrimeMeridian meridian  = createPrimeMeridian(names, angularUnit);
                 final GeodeticDatum datum     = objectFactory().createGeodeticDatum(properties(name), ellipsoid, meridian);
                 name = Utilities.toUpperCase(name, Characters.Filter.LETTERS_AND_DIGITS);
                 lastName = datum.getName();
@@ -994,10 +1037,10 @@ final class CRSBuilder {
      */
     private void verify(final GeodeticDatum datum, final Unit<Angle> angularUnit, final Unit<Length> linearUnit) {
         final PrimeMeridian pm = datum.getPrimeMeridian();
-        verifyIdentifier(pm, GeoKeys.GeogPrimeMeridian);
+        verifyIdentifier(pm, GeoKeys.PrimeMeridian);
         verify(pm, angularUnit);
         final Ellipsoid ellipsoid = datum.getEllipsoid();
-        verifyIdentifier(ellipsoid, GeoKeys.GeogEllipsoid);
+        verifyIdentifier(ellipsoid, GeoKeys.Ellipsoid);
         verify(ellipsoid, linearUnit);
     }
 
@@ -1006,18 +1049,86 @@ final class CRSBuilder {
 
 
     /**
+     * Splits the {@link GeoKeys#GeogCitation} value into its prime meridian, ellipsoid, datum and CRS name components.
+     * This method is intended to parse geographic CRS names written like below:
+     *
+     * {@preformat text
+     *   GCS Name = wgs84|Datum = unknown|Ellipsoid = WGS_1984|Primem = Greenwich|
+     * }
+     *
+     * The keywords of both Well Known Text (WKT) version 1 and 2 are accepted as keys for the datum, ellipsoid and
+     * prime meridian names. All other keys are presumed to be for the geographic CRS name. If the given string does
+     * not contain the pipe ({@code '|'}) separator, then the whole string is presumed to be the geographic CRS name.
+     *
+     * <p>This method returns an array where component names are stored at index {@link #PRIMEM}, {@link #ELLIPSOID},
+     * {@link #DATUM} and {@link #GCRS}. Any array element can be null if no name were found for that component.</p>
+     */
+    static String[] splitName(final String name) {
+        final String[] names = new String[GCRS + 1];
+        final String[] components = (String[]) CharSequences.split(name, '|');
+        switch (components.length) {
+            case 0: break;
+            case 1: names[GCRS] = name; break;
+            default: {
+                for (String value : components) {
+                    final int s = value.indexOf('=');
+                    int type = GCRS;
+                    if (s >= 0) {
+                        final int length = CharSequences.skipTrailingWhitespaces(value, 0, s);
+                        if (length >= MIN_KEY_LENGTH) {
+                            for (int t=0; t < NAME_KEYS.length; t++) {
+                                if (value.regionMatches(true, 0, NAME_KEYS[t], 0, length)) {
+                                    type = t/2;
+                                    break;
+                                }
+                            }
+                        }
+                        value = value.substring(CharSequences.skipLeadingWhitespaces(value, s+1, value.length()));
+                    }
+                    if (!value.isEmpty()) {
+                        if (names[type] != null) {
+                            value = names[type] + ' ' + value;
+                        }
+                        names[type] = value;
+                    }
+                }
+                break;
+            }
+        }
+        return names;
+    }
+
+    /**
+     * Returns the name at the given index if non-null. If that name is null, search for a name is a sister element
+     * (e.g. the datum name or the geographic CRS name). If none is found, returns {@code null}.
+     */
+    private static String getOrDefault(final String[] names, int component) {
+        String c = names[component];
+        if (c == null) {
+            // Prime meridian must be excluded in the search below.
+            for (component = PRIMEM; ++component < names.length; component++) {
+                c = names[component];
+                if (c != null) {
+                    break;
+                }
+            }
+        }
+        return c;
+    }
+
+    /**
      * Creates a geographic CRS from an EPSG code or from user-defined parameters.
      * The GeoTIFF values used by this method are:
      *
      * <ul>
      *   <li>A code given by {@link GeoKeys#GeographicType}.</li>
      *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
-     *     <li>a prime meridian value given by {@link GeoKeys#GeogPrimeMeridianLong},</li>
+     *     <li>a prime meridian value given by {@link GeoKeys#PrimeMeridianLong},</li>
      *     <li>a CRS name given by {@link GeoKeys#GeogCitation},</li>
      *     <li>a datum definition.</li>
      *   </ul></li>
-     *   <li>A unit code given by {@link GeoKeys#GeogAngularUnits} (optional).</li>
-     *   <li>A unit scale factor given by {@link GeoKeys#GeogAngularUnitSize} (optional).</li>
+     *   <li>A unit code given by {@link GeoKeys#AngularUnits} (optional).</li>
+     *   <li>A unit scale factor given by {@link GeoKeys#AngularUnitSize} (optional).</li>
      * </ul>
      *
      * @param  rightHanded  whether to force longitude before latitude axis.
@@ -1039,15 +1150,15 @@ final class CRSBuilder {
                  * Creates the geodetic datum, then a geographic CRS assuming (longitude, latitude) axis order.
                  * We use the coordinate system of CRS:84 as a template and modify its unit of measurement if needed.
                  */
-                final String             name = getAsString(GeoKeys.GeogCitation);
-                final Unit<Length> linearUnit = createUnit(GeoKeys.GeogLinearUnits,  GeoKeys.GeogLinearUnitSize, Length.class, Units.METRE);
-                final Unit<Angle> angularUnit = createUnit(GeoKeys.GeogAngularUnits, GeoKeys.GeogAngularUnitSize, Angle.class, Units.DEGREE);
-                final GeodeticDatum     datum = createGeodeticDatum(name, angularUnit, linearUnit);
+                final String[] names = splitName(getAsString(GeoKeys.GeogCitation));
+                final Unit<Length> linearUnit = createUnit(GeoKeys.GeogLinearUnits, GeoKeys.GeogLinearUnitSize, Length.class, Units.METRE);
+                final Unit<Angle> angularUnit = createUnit(GeoKeys.AngularUnits,    GeoKeys.AngularUnitSize, Angle.class, Units.DEGREE);
+                final GeodeticDatum     datum = createGeodeticDatum(names, angularUnit, linearUnit);
                 EllipsoidalCS cs = CommonCRS.defaultGeographic().getCoordinateSystem();
                 if (!Units.DEGREE.equals(angularUnit)) {
                     cs = replaceAngularUnit(cs, angularUnit);
                 }
-                final GeographicCRS crs = objectFactory().createGeographicCRS(properties(name), datum, cs);
+                final GeographicCRS crs = objectFactory().createGeographicCRS(properties(getOrDefault(names, GCRS)), datum, cs);
                 lastName = crs.getName();
                 return crs;
             }
@@ -1079,10 +1190,10 @@ final class CRSBuilder {
          * Note: current createUnit(…) implementation does not allow us to distinguish whether METRE ou DEGREE units
          * were specified in the GeoTIFF file or if we got the default values. We do not compare units of that reason.
          */
-        final Unit<Length> linearUnit = createUnit(GeoKeys.GeogLinearUnits,  GeoKeys.GeogLinearUnitSize, Length.class, Units.METRE);
-        final Unit<Angle> angularUnit = createUnit(GeoKeys.GeogAngularUnits, GeoKeys.GeogAngularUnitSize, Angle.class, Units.DEGREE);
+        final Unit<Length> linearUnit = createUnit(GeoKeys.GeogLinearUnits, GeoKeys.GeogLinearUnitSize, Length.class, Units.METRE);
+        final Unit<Angle> angularUnit = createUnit(GeoKeys.AngularUnits,    GeoKeys.AngularUnitSize, Angle.class, Units.DEGREE);
         final GeodeticDatum datum = crs.getDatum();
-        verifyIdentifier(datum, GeoKeys.GeogGeodeticDatum);
+        verifyIdentifier(datum, GeoKeys.GeodeticDatum);
         verify(datum, angularUnit, linearUnit);
     }
 
@@ -1099,10 +1210,10 @@ final class CRSBuilder {
      *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
      *     <li>a name given by {@link GeoKeys#PCSCitation},</li>
      *     <li>a {@link CoordinateOperation} given by {@link GeoKeys#Projection},</li>
-     *     <li>an {@link OperationMethod} given by {@link GeoKeys#ProjCoordTrans}.</li>
+     *     <li>an {@link OperationMethod} given by {@link GeoKeys#CoordTrans}.</li>
      *   </ul></li>
-     *   <li>A unit code given by {@link GeoKeys#ProjLinearUnits} (optional).</li>
-     *   <li>A unit scale factor given by {@link GeoKeys#ProjLinearUnitSize} (optional).</li>
+     *   <li>A unit code given by {@link GeoKeys#LinearUnits} (optional).</li>
+     *   <li>A unit scale factor given by {@link GeoKeys#LinearUnitSize} (optional).</li>
      * </ul>
      *
      * @throws NoSuchElementException if a mandatory value is missing.
@@ -1113,7 +1224,7 @@ final class CRSBuilder {
      * @see #createGeographicCRS(boolean)
      * @see #createConversion(String)
      */
-    private CoordinateReferenceSystem createProjectedCRS() throws FactoryException {
+    private ProjectedCRS createProjectedCRS() throws FactoryException {
         final int epsg = getAsInteger(GeoKeys.ProjectedCSType);
         switch (epsg) {
             case GeoCodes.undefined: {
@@ -1122,13 +1233,18 @@ final class CRSBuilder {
             case GeoCodes.userDefined: {
                 /*
                  * If the CRS is user-defined, we have to parse many components (base CRS, datum, unit, etc.)
-                 * and build the projected CRS from them.
+                 * and build the projected CRS from them. Note that some GeoTIFF files put the projection name
+                 * in the Citation key instead of PCSCitation.
                  */
-                final String name = getAsString(GeoKeys.PCSCitation);
-                final Conversion projection = createConversion(name);
-                final GeographicCRS baseCRS = createGeographicCRS(false);
+                String name = getAsString(GeoKeys.PCSCitation);
+                if (name == null) {
+                    name = getAsString(GeoKeys.Citation);
+                    // Note that Citation has been removed from the map, so it will not be used by 'complete(MetadataBuilder).
+                }
+                final GeographicCRS baseCRS    = createGeographicCRS(false);
+                final Conversion    projection = createConversion(name);
+                final Unit<Length>  unit       = createUnit(GeoKeys.LinearUnits, GeoKeys.LinearUnitSize, Length.class, Units.METRE);
                 CartesianCS cs = epsgFactory().createCartesianCS(String.valueOf(Constants.EPSG_PROJECTED_CS));
-                final Unit<Length> unit = createUnit(GeoKeys.ProjLinearUnits, GeoKeys.ProjLinearUnitSize, Length.class, Units.METRE);
                 if (!Units.METRE.equals(unit)) {
                     cs = replaceLinearUnit(cs, unit);
                 }
@@ -1160,6 +1276,9 @@ final class CRSBuilder {
         final GeographicCRS baseCRS = crs.getBaseCRS();
         verifyIdentifier(baseCRS, GeoKeys.GeographicType);
         verify(baseCRS);
+        final Conversion projection = crs.getConversionFromBase();
+        verifyIdentifier(projection, GeoKeys.Projection);
+        verify(projection);
     }
 
     /**
@@ -1177,20 +1296,33 @@ final class CRSBuilder {
                 throw new NoSuchElementException(missingValue(GeoKeys.Projection));
             }
             case GeoCodes.userDefined: {
-                final String              type        = getMandatoryString(GeoKeys.ProjCoordTrans);
-                final OperationMethod     method      = operationFactory().getOperationMethod(type);
-                final ParameterValueGroup parameters  = method.getParameters().createValue();
+                final String              type       = getMandatoryString(GeoKeys.CoordTrans);
+                final OperationMethod     method     = operationFactory().getOperationMethod(type);
+                final ParameterValueGroup parameters = method.getParameters().createValue();
                 final Conversion c = operationFactory().createDefiningConversion(properties(name), method, parameters);
                 lastName = c.getName();
                 return c;
             }
             default: {
-                return (Conversion) epsgFactory().createCoordinateOperation(String.valueOf(epsg));
+                final Conversion projection = (Conversion) epsgFactory().createCoordinateOperation(String.valueOf(epsg));
+                verify(projection);
+                return projection;
             }
         }
     }
 
     /**
+     * Verifies if the user-defined conversion created from GeoTIFF values
+     * matches the given conversion created from the EPSG geodetic dataset.
+     * This method does not verify the EPSG code of the given conversion.
+     *
+     * @param  projection  the conversion created from the EPSG geodetic dataset.
+     */
+    private void verify(final Conversion projection) throws FactoryException {
+        // TODO
+    }
+
+    /**
      * Returns a string representation of the keys and associated values in this {@code CRSBuilder}.
      */
     @Debug

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -40,57 +40,57 @@ final class GeoKeys {
     }
 
     // 6.2.1 GeoTIFF Configuration Keys
-    /** Section 6.3.1.1 Codes. */ public static final short ModelType                = 1024;
-    /** Section 6.3.1.2 Codes. */ public static final short RasterType               = 1025;
-    /** Documentation.         */ public static final short Citation                 = 1026;
+    /** Section 6.3.1.1 Codes. */ public static final short ModelType            = 1024;
+    /** Section 6.3.1.2 Codes. */ public static final short RasterType           = 1025;
+    /** Documentation.         */ public static final short Citation             = 1026;
 
     // 6.2.2 Geographic CS Parameter Keys
-    /** Section 6.3.2.1 Codes. */ public static final short GeographicType           = 2048;
-    /** Documentation.         */ public static final short GeogCitation             = 2049;
-    /** Section 6.3.2.2 Codes. */ public static final short GeogGeodeticDatum        = 2050;
-    /** Section 6.3.2.4 codes. */ public static final short GeogPrimeMeridian        = 2051;
-    /** Section 6.3.1.3 Codes. */ public static final short GeogLinearUnits          = 2052;
-    /** Relative to meters.    */ public static final short GeogLinearUnitSize       = 2053;
-    /** Section 6.3.1.4 Codes. */ public static final short GeogAngularUnits         = 2054;
-    /** Relative to radians.   */ public static final short GeogAngularUnitSize      = 2055;
-    /** Section 6.3.2.3 Codes. */ public static final short GeogEllipsoid            = 2056;
-    /** In GeogLinearUnits.    */ public static final short GeogSemiMajorAxis        = 2057;
-    /** In GeogLinearUnits.    */ public static final short GeogSemiMinorAxis        = 2058;
-    /** A ratio.               */ public static final short GeogInvFlattening        = 2059;
-    /** Section 6.3.1.4 Codes. */ public static final short GeogAzimuthUnits         = 2060;
-    /** In GeogAngularUnit.    */ public static final short GeogPrimeMeridianLong    = 2061;
+    /** Section 6.3.2.1 Codes. */ public static final short GeographicType       = 2048;
+    /** Documentation.         */ public static final short GeogCitation         = 2049;
+    /** Section 6.3.2.2 Codes. */ public static final short GeodeticDatum        = 2050;
+    /** Section 6.3.2.4 codes. */ public static final short PrimeMeridian        = 2051;
+    /** Section 6.3.1.3 Codes. */ public static final short GeogLinearUnits      = 2052;
+    /** Relative to meters.    */ public static final short GeogLinearUnitSize   = 2053;
+    /** Section 6.3.1.4 Codes. */ public static final short AngularUnits         = 2054;
+    /** Relative to radians.   */ public static final short AngularUnitSize      = 2055;
+    /** Section 6.3.2.3 Codes. */ public static final short Ellipsoid            = 2056;
+    /** In GeogLinearUnits.    */ public static final short SemiMajorAxis        = 2057;
+    /** In GeogLinearUnits.    */ public static final short SemiMinorAxis        = 2058;
+    /** A ratio.               */ public static final short InvFlattening        = 2059;
+    /** Section 6.3.1.4 Codes. */ public static final short AzimuthUnits         = 2060;
+    /** In AngularUnit.        */ public static final short PrimeMeridianLong    = 2061;
 
     // 6.2.3 Projected CS Parameter Keys
-    /** Section 6.3.3.1 codes. */ public static final short ProjectedCSType          = 3072;
-    /** Documentation.         */ public static final short PCSCitation              = 3073;
-    /** Section 6.3.3.2 codes. */ public static final short Projection               = 3074;
-    /** Section 6.3.3.3 codes. */ public static final short ProjCoordTrans           = 3075;
-    /** Section 6.3.1.3 codes. */ public static final short ProjLinearUnits          = 3076;
-    /** Relative to meters.    */ public static final short ProjLinearUnitSize       = 3077;
-    /** In GeogAngularUnit.    */ public static final short ProjStdParallel1         = 3078;
-    /** In GeogAngularUnit.    */ public static final short ProjStdParallel2         = 3079;
-    /** In GeogAngularUnit.    */ public static final short ProjNatOriginLong        = 3080;
-    /** In GeogAngularUnit.    */ public static final short ProjNatOriginLat         = 3081;
-    /** In ProjLinearUnits.    */ public static final short ProjFalseEasting         = 3082;
-    /** In ProjLinearUnits.    */ public static final short ProjFalseNorthing        = 3083;
-    /** In GeogAngularUnit.    */ public static final short ProjFalseOriginLong      = 3084;
-    /** In GeogAngularUnit.    */ public static final short ProjFalseOriginLat       = 3085;
-    /** In ProjLinearUnits.    */ public static final short ProjFalseOriginEasting   = 3086;
-    /** In ProjLinearUnits.    */ public static final short ProjFalseOriginNorthing  = 3087;
-    /** In GeogAngularUnit.    */ public static final short ProjCenterLong           = 3088;
-    /** In GeogAngularUnit.    */ public static final short ProjCenterLat            = 3089;
-    /** In ProjLinearUnits.    */ public static final short ProjCenterEasting        = 3090;
-    /** In ProjLinearUnits.    */ public static final short ProjCenterNorthing       = 3091;
-    /** A ratio.               */ public static final short ProjScaleAtNatOrigin     = 3092;
-    /** A ratio.               */ public static final short ProjScaleAtCenter        = 3093;
-    /** In GeogAzimuthUnit.    */ public static final short ProjAzimuthAngle         = 3094;
-    /** In GeogAngularUnit.    */ public static final short ProjStraightVertPoleLong = 3095;
+    /** Section 6.3.3.1 codes. */ public static final short ProjectedCSType      = 3072;
+    /** Documentation.         */ public static final short PCSCitation          = 3073;
+    /** Section 6.3.3.2 codes. */ public static final short Projection           = 3074;
+    /** Section 6.3.3.3 codes. */ public static final short CoordTrans           = 3075;
+    /** Section 6.3.1.3 codes. */ public static final short LinearUnits          = 3076;
+    /** Relative to meters.    */ public static final short LinearUnitSize       = 3077;
+    /** In AngularUnit.        */ public static final short StdParallel1         = 3078;
+    /** In AngularUnit.        */ public static final short StdParallel2         = 3079;
+    /** In AngularUnit.        */ public static final short NatOriginLong        = 3080;
+    /** In AngularUnit.        */ public static final short NatOriginLat         = 3081;
+    /** In LinearUnits.        */ public static final short FalseEasting         = 3082;
+    /** In LinearUnits.        */ public static final short FalseNorthing        = 3083;
+    /** In AngularUnit.        */ public static final short FalseOriginLong      = 3084;
+    /** In AngularUnit.        */ public static final short FalseOriginLat       = 3085;
+    /** In LinearUnits.        */ public static final short FalseOriginEasting   = 3086;
+    /** In LinearUnits.        */ public static final short FalseOriginNorthing  = 3087;
+    /** In AngularUnit.        */ public static final short CenterLong           = 3088;
+    /** In AngularUnit.        */ public static final short CenterLat            = 3089;
+    /** In LinearUnits.        */ public static final short CenterEasting        = 3090;
+    /** In LinearUnits.        */ public static final short CenterNorthing       = 3091;
+    /** A ratio.               */ public static final short ScaleAtNatOrigin     = 3092;
+    /** A ratio.               */ public static final short ScaleAtCenter        = 3093;
+    /** In AzimuthUnit.        */ public static final short AzimuthAngle         = 3094;
+    /** In AngularUnit.        */ public static final short StraightVertPoleLong = 3095;
 
     // 6.2.4 Vertical CS Keys
-    /** Section 6.3.4.1 codes. */ public static final short VerticalCSType           = 4096;
-    /** Documentation.         */ public static final short VerticalCitation         = 4097;
-    /** Section 6.3.4.2 codes. */ public static final short VerticalDatum            = 4098;
-    /** Section 6.3.1.3 codes. */ public static final short VerticalUnits            = 4099;
+    /** Section 6.3.4.1 codes. */ public static final short VerticalCSType       = 4096;
+    /** Documentation.         */ public static final short VerticalCitation     = 4097;
+    /** Section 6.3.4.2 codes. */ public static final short VerticalDatum        = 4098;
+    /** Section 6.3.1.3 codes. */ public static final short VerticalUnits        = 4099;
 
     /**
      * Returns the name of the given key. Implementation of this method is inefficient,

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -40,12 +40,18 @@ import org.apache.sis.internal.geotiff.R
  */
 abstract class GeoTIFF implements Closeable {
     /**
-     * The timezone specified at construction time, or {@code null} for the default.
+     * The timezone for the date and time parsing, or {@code null} for the default.
      * This is not yet configurable, but may become in a future version.
      */
     private static final TimeZone TIMEZONE = null;
 
     /**
+     * The locale to use for parsers or formatter. This is <strong>not</strong> the locale
+     * for warnings or other messages emitted to the users.
+     */
+    static final Locale LOCALE = Locale.US;
+
+    /**
      * The store which created this reader or writer.
      */
     final GeoTiffStore owner;
@@ -81,7 +87,7 @@ abstract class GeoTIFF implements Closea
      */
     final DateFormat getDateFormat() {
         if (dateFormat == null) {
-            dateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.US);
+            dateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", LOCALE);
             if (TIMEZONE != null) {
                 dateFormat.setTimeZone(TIMEZONE);
             }

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.util.NoSuchElementException;
 import java.nio.charset.Charset;
 import javax.measure.Unit;
 import javax.measure.quantity.Length;
@@ -1028,8 +1029,14 @@ final class ImageFileDirectory {
          */
         if (geoKeyDirectory != null) {
             final CRSBuilder helper = new CRSBuilder(reader);
-            metadata.add(helper.build(geoKeyDirectory, numericGeoParameters, asciiGeoParameters));
-            helper.complete(metadata);
+            try {
+                metadata.add(helper.build(geoKeyDirectory, numericGeoParameters, asciiGeoParameters));
+                helper.complete(metadata);
+            } catch (ClassCastException e) {
+                reader.owner.warning(null, e);
+            } catch (NumberFormatException | NoSuchElementException e) {
+                // Ignore - a warning with a better message has already been emitted.
+            }
             geoKeyDirectory      = null;            // Not needed anymore, so let GC do its work.
             numericGeoParameters = null;
             asciiGeoParameters   = null;

Added: sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java?rev=1772421&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java (added)
+++ sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License)); Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing)); software
+ * distributed under the License is distributed on an "AS IS" BASIS));
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND)); either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.geotiff;
+
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests the {@link CRSBuilder} base class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public final strictfp class CRSBuilderTest extends TestCase {
+    /**
+     * Tests {@link CRSBuilder#splitName(String)}. The string used for this test is:
+     *
+     * {@preformat text
+     *   GCS Name = wgs84|Datum = unknown|Ellipsoid = WGS_1984|Primem = Greenwich|
+     * }
+     */
+    @Test
+    public void testSplitName() {
+        final String[] names = CRSBuilder.splitName("GCS Name = wgs84|Datum = unknown|Ellipsoid = WGS_1984|Primem = Greenwich|");
+        assertEquals("GCRS",      "wgs84",    names[CRSBuilder.GCRS]);
+        assertEquals("DATUM",     "unknown",  names[CRSBuilder.DATUM]);
+        assertEquals("ELLIPSOID", "WGS_1984", names[CRSBuilder.ELLIPSOID]);
+        assertEquals("PRIMEM",    "Greenwich", names[CRSBuilder.PRIMEM]);
+    }
+
+    /**
+     * Tests {@link CRSBuilder#splitName(String)} on a string that should not be splitted.
+     */
+    @Test
+    public void testNoSplit() {
+        final String[] names = CRSBuilder.splitName("WGS 84");
+        assertEquals("GCRS", "WGS 84", names[CRSBuilder.GCRS]);
+        assertNull  ("DATUM",          names[CRSBuilder.DATUM]);
+        assertNull  ("ELLIPSOID",      names[CRSBuilder.ELLIPSOID]);
+        assertNull  ("PRIMEM",         names[CRSBuilder.PRIMEM]);
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/CRSBuilderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoIdentifiers.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoIdentifiers.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoIdentifiers.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/GeoIdentifiers.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -48,44 +48,44 @@ final class GeoIdentifiers {
      *   [        32767]  =  user-defined
      *   [32768 … 65535]  =  Private User Implementations
      */
-    public static final short CT_TransverseMercator =             1;
-    public static final short CT_TransvMercator_Modified_Alaska = 2;
-    public static final short CT_ObliqueMercator =                3;
-    public static final short CT_ObliqueMercator_Laborde =        4;
-    public static final short CT_ObliqueMercator_Rosenmund =      5;
-    public static final short CT_ObliqueMercator_Spherical =      6;
-    public static final short CT_Mercator =                       7;
-    public static final short CT_LambertConfConic_2SP =           8;
-    public static final short CT_LambertConfConic_1SP =           9;
-    public static final short CT_LambertAzimEqualArea =           10;
-    public static final short CT_AlbersEqualArea =                11;
-    public static final short CT_AzimuthalEquidistant =           12;
-    public static final short CT_EquidistantConic =               13;
-    public static final short CT_Stereographic =                  14;
-    public static final short CT_PolarStereographic =             15;
-    public static final short CT_ObliqueStereographic =           16;
-    public static final short CT_Equirectangular =                17;
-    public static final short CT_CassiniSoldner =                 18;
-    public static final short CT_Gnomonic =                       19;
-    public static final short CT_MillerCylindrical =              20;
-    public static final short CT_Orthographic =                   21;
-    public static final short CT_Polyconic =                      22;
-    public static final short CT_Robinson =                       23;
-    public static final short CT_Sinusoidal =                     24;
-    public static final short CT_VanDerGrinten =                  25;
-    public static final short CT_NewZealandMapGrid =              26;
-    public static final short CT_TransvMercator_SouthOriented=    27;
+    public static final short CT_TransverseMercator             =  1;
+    public static final short CT_TransvMercator_Modified_Alaska =  2;
+    public static final short CT_ObliqueMercator                =  3;
+    public static final short CT_ObliqueMercator_Laborde        =  4;
+    public static final short CT_ObliqueMercator_Rosenmund      =  5;
+    public static final short CT_ObliqueMercator_Spherical      =  6;
+    public static final short CT_Mercator                       =  7;
+    public static final short CT_LambertConfConic_2SP           =  8;
+    public static final short CT_LambertConfConic_1SP           =  9;
+    public static final short CT_LambertAzimEqualArea           = 10;
+    public static final short CT_AlbersEqualArea                = 11;
+    public static final short CT_AzimuthalEquidistant           = 12;
+    public static final short CT_EquidistantConic               = 13;
+    public static final short CT_Stereographic                  = 14;
+    public static final short CT_PolarStereographic             = 15;
+    public static final short CT_ObliqueStereographic           = 16;
+    public static final short CT_Equirectangular                = 17;
+    public static final short CT_CassiniSoldner                 = 18;
+    public static final short CT_Gnomonic                       = 19;
+    public static final short CT_MillerCylindrical              = 20;
+    public static final short CT_Orthographic                   = 21;
+    public static final short CT_Polyconic                      = 22;
+    public static final short CT_Robinson                       = 23;
+    public static final short CT_Sinusoidal                     = 24;
+    public static final short CT_VanDerGrinten                  = 25;
+    public static final short CT_NewZealandMapGrid              = 26;
+    public static final short CT_TransvMercator_SouthOriented   = 27;
 
     // Aliases:
-    public static final short CT_AlaskaConformal =                CT_TransvMercator_Modified_Alaska;
-    public static final short CT_TransvEquidistCylindrical =      CT_CassiniSoldner;
-    public static final short CT_ObliqueMercator_Hotine =         CT_ObliqueMercator;
-    public static final short CT_SwissObliqueCylindrical =        CT_ObliqueMercator_Rosenmund;
-    public static final short CT_GaussBoaga =                     CT_TransverseMercator;
-    public static final short CT_GaussKruger =                    CT_TransverseMercator;
-    public static final short CT_LambertConfConic =               CT_LambertConfConic_2SP ;
-    public static final short CT_LambertConfConic_Helmert =       CT_LambertConfConic_1SP;
-    public static final short CT_SouthOrientedGaussConformal =    CT_TransvMercator_SouthOriented;
+    public static final short CT_AlaskaConformal              =  CT_TransvMercator_Modified_Alaska;
+    public static final short CT_TransvEquidistCylindrical    =  CT_CassiniSoldner;
+    public static final short CT_ObliqueMercator_Hotine       =  CT_ObliqueMercator;
+    public static final short CT_SwissObliqueCylindrical      =  CT_ObliqueMercator_Rosenmund;
+    public static final short CT_GaussBoaga                   =  CT_TransverseMercator;
+    public static final short CT_GaussKruger                  =  CT_TransverseMercator;
+    public static final short CT_LambertConfConic             =  CT_LambertConfConic_2SP ;
+    public static final short CT_LambertConfConic_Helmert     =  CT_LambertConfConic_1SP;
+    public static final short CT_SouthOrientedGaussConformal  =  CT_TransvMercator_SouthOriented;
 
     /*
      * 6.3.1.3 Linear Units Codes

Modified: sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java?rev=1772421&r1=1772420&r2=1772421&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/test/java/org/apache/sis/test/suite/GeoTiffTestSuite.java [UTF-8] Sat Dec  3 00:16:38 2016
@@ -31,7 +31,8 @@ import org.junit.BeforeClass;
  */
 @Suite.SuiteClasses({
     org.apache.sis.storage.geotiff.TypeTest.class,
-    org.apache.sis.storage.geotiff.CompressionTest.class
+    org.apache.sis.storage.geotiff.CompressionTest.class,
+    org.apache.sis.storage.geotiff.CRSBuilderTest.class
 })
 public final strictfp class GeoTiffTestSuite extends TestSuite {
     /**



Mime
View raw message