You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/04/22 17:17:55 UTC

svn commit: r1792306 [2/2] - in /sis/trunk: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/main/java/org/apache/sis/feature/builder/ core/sis-feature/src/test/java/org/apache/sis/feature/ core/sis-metadata/src/main/java/...

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -98,6 +98,12 @@ public final class Resources extends Ind
         public static final short IgnoredTag_1 = 7;
 
         /**
+         * Map projection parameter \u201c{2}\u201d will be ignored because its value ({3}) is inconsistent with
+         * the \u201c{0} = {1}\u201d parameter.
+         */
+        public static final short InconsistentMapProjParameter_4 = 24;
+
+        /**
          * TIFF image \u201c{0}\u201d shall be either tiled or organized into strips.
          */
         public static final short InconsistentTileStrip_1 = 8;
@@ -155,6 +161,11 @@ public final class Resources extends Ind
         public static final short UnexpectedTileCount_3 = 18;
 
         /**
+         * TIFF file \u201c{0}\u201d uses an unknown coordinate reference system.
+         */
+        public static final short UnknownCRS_1 = 22;
+
+        /**
          * Coordinate system kind {0} is unsupported.
          */
         public static final short UnsupportedCoordinateSystemKind_1 = 19;
@@ -168,6 +179,11 @@ public final class Resources extends Ind
          * Unsupported storage location for the \u201c{0}\u201d GeoTIFF value.
          */
         public static final short UnsupportedGeoKeyStorage_1 = 21;
+
+        /**
+         * TIFF file \u201c{0}\u201d uses an unsupported map projection.
+         */
+        public static final short UnsupportedProjectionMethod_1 = 23;
     }
 
     /**

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] Sat Apr 22 17:17:54 2017
@@ -26,6 +26,7 @@ DefaultValueForAttribute_2        = No v
 DitheringOrHalftoningApplied_2    = An ordered dither or halftone technique has been applied to the image data. The dithering or halftoning matrix size is {0}\u00d7{1}.
 IgnoredTag_1                      = The \u201c{0}\u201d TIFF tag has been ignored.
 IgnoredGeoKeys_1                  = The following GeoTIFF keys have been ignored: {0}
+InconsistentMapProjParameter_4    = Map projection parameter \u201c{2}\u201d will be ignored because its value ({3}) is inconsistent with the \u201c{0} = {1}\u201d parameter.
 InconsistentTileStrip_1           = TIFF image \u201c{0}\u201d shall be either tiled or organized into strips.
 InvalidGeoValue_2                 = \u201c{1}\u201d is not a valid value for the \u201c{0}\u201d GeoTIFF key.
 ListTooShort_3                    = TIFF tag \u201c{0}\u201d shall contain at least {1} values but found only {2}.
@@ -37,6 +38,8 @@ RandomizedProcessApplied          = A ra
 UnexpectedListOfValues_2          = A single value was expected for the \u201c{0}\u201d key but {1} values have been found.
 UnexpectedParameter_2             = The \u201c{1}\u201d parameter was not expected for the \u201c{0}\u201d projection method.
 UnexpectedTileCount_3             = Found {2} tiles or strips in the \u201c{0}\u201d file while {1} were expected.
+UnknownCRS_1                      = TIFF file \u201c{0}\u201d uses an unknown coordinate reference system.
 UnsupportedCoordinateSystemKind_1 = Coordinate system kind {0} is unsupported.
 UnsupportedGeoKeyDirectory_1      = Version {0}\u00a0of GeoTIFF key directory is not supported.
 UnsupportedGeoKeyStorage_1        = Unsupported storage location for the \u201c{0}\u201d GeoTIFF value.
+UnsupportedProjectionMethod_1     = TIFF file \u201c{0}\u201d uses an unsupported map projection.

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] Sat Apr 22 17:17:54 2017
@@ -31,6 +31,7 @@ DefaultValueForAttribute_2        = Aucu
 DitheringOrHalftoningApplied_2    = Un tramage ordonn\u00e9 ou une technique en demi-teinte a \u00e9t\u00e9 appliqu\u00e9. La taille de la matrice de tramage est {0}\u00d7{1}.
 IgnoredTag_1                      = Le tag TIFF \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 ignor\u00e9.
 IgnoredGeoKeys_1                  = Les cl\u00e9s GeoTIFF suivantes ont \u00e9t\u00e9 ignor\u00e9es\u2008: {0}
+InconsistentMapProjParameter_4    = Le param\u00e8tre de projection cartographique \u00ab\u202f{2}\u202f\u00bb sera ignor\u00e9 car sa valeur ({3}) est incoh\u00e9rente avec le param\u00e8tre \u00ab\u202f{0} = {1}\u202f\u00bb.
 InconsistentTileStrip_1           = L\u2019image TIFF \u00ab\u202f{0}\u202f\u00bb doit \u00eatre soit tuil\u00e9e, soit organis\u00e9e par bandes.
 InvalidGeoValue_2                 = La valeur \u00ab\u202f{1}\u202f\u00bb n\u2019est pas valide pour la cl\u00e9 GeoTIFF \u00ab\u202f{0}\u202f\u00bb.
 ListTooShort_3                    = Le tag TIFF \u00ab\u202f{0}\u202f\u00bb devrait contenir au moins {1} valeurs alors qu\u2019on n\u2019en a trouv\u00e9 que {2}.
@@ -42,6 +43,8 @@ RandomizedProcessApplied          = Un p
 UnexpectedListOfValues_2          = Une seule valeur \u00e9tait attendue pour la cl\u00e9 \u00ab\u202f{0}\u202f\u00bb, mais on en a trouv\u00e9es {1}.
 UnexpectedParameter_2             = Le param\u00e8tre \u00ab\u202f{1}\u202f\u00bb est inattendu pour la m\u00e9thode de projection \u00ab\u202f{0}\u202f\u00bb.
 UnexpectedTileCount_3             = {2} tuiles ont \u00e9t\u00e9 trouv\u00e9es dans le fichier \u00ab\u202f{0}\u202f\u00bb alors qu\u2019on en attendait {1}.
+UnknownCRS_1                      = Le fichier TIFF \u00ab\u202f{0}\u202f\u00bb utilise un syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es inconnu.
 UnsupportedCoordinateSystemKind_1 = Le type de syst\u00e8me de coordonn\u00e9es {0} n\u2019est pas support\u00e9.
 UnsupportedGeoKeyDirectory_1      = La version {0} du r\u00e9pertoire de cl\u00e9s GeoTIFF n\u2019est pas support\u00e9e.
 UnsupportedGeoKeyStorage_1        = La valeur GeoTIFF \u00ab\u202f{0}\u202f\u00bb utilise un mode de stockage non-support\u00e9.
+UnsupportedProjectionMethod_1     = Le fichier TIFF \u00ab\u202f{0}\u202f\u00bb utilise une projection cartographique non-support\u00e9e.

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -69,7 +69,6 @@ import org.apache.sis.internal.util.Util
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.math.Vector;
 import org.apache.sis.measure.Units;
-import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
@@ -80,13 +79,18 @@ 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.referencing.operation.DefaultCoordinateOperationFactory;
+import org.apache.sis.util.iso.DefaultNameSpace;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.Debug;
 
 import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
+
 
 /**
  * Helper class for building a {@link CoordinateReferenceSystem} from information found in TIFF tags.
@@ -246,6 +250,13 @@ final class CRSBuilder {
     private Identifier lastName;
 
     /**
+     * {@code true} when an exception has been thrown but this {@code CRSBuilder} already reported a warning,
+     * so there is no need for the caller to report a warning again. {@code CRSBuilder} sometime reports warnings
+     * itself when it can provide a better warning message than what the caller can do.
+     */
+    boolean alreadyReported;
+
+    /**
      * Creates a new builder of coordinate reference systems.
      *
      * @param reader  where to report warnings if any.
@@ -393,6 +404,7 @@ final class CRSBuilder {
             return Integer.parseInt(value.toString());
         } catch (NumberFormatException e) {
             invalidValue(key, value);
+            alreadyReported = true;
             throw e;
         }
     }
@@ -416,6 +428,7 @@ final class CRSBuilder {
             return Double.parseDouble(value.toString());
         } catch (NumberFormatException e) {
             invalidValue(key, value);
+            alreadyReported = true;
             throw e;
         }
     }
@@ -434,6 +447,7 @@ final class CRSBuilder {
         if (value != null) {
             return value;
         }
+        alreadyReported = true;
         throw new NoSuchElementException(missingValue(key));
     }
 
@@ -452,6 +466,7 @@ final class CRSBuilder {
         if (!Double.isNaN(value)) {
             return value;
         }
+        alreadyReported = true;
         throw new NoSuchElementException(missingValue(key));
     }
 
@@ -976,6 +991,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.Ellipsoid);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
@@ -1058,6 +1074,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeodeticDatum);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
@@ -1179,7 +1196,7 @@ final class CRSBuilder {
     }
 
     /**
-     * Returns the name at the given index if non-null. If that name is null, search for a name is a sister element
+     * Returns the name at the given index if non-null. If that name is null, search for a name in 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) {
@@ -1224,6 +1241,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeographicType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeographicType));
             }
             case GeoCodes.userDefined: {
@@ -1292,6 +1310,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeographicType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeographicType));
             }
             case GeoCodes.userDefined: {
@@ -1353,6 +1372,51 @@ final class CRSBuilder {
     //////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
+     * Map projection parameters to be considered as aliases. This table is used for reading GeoTIFF files
+     * that are not really well-formed, but for which we can reasonably guess what was the producer intend
+     * and which parameters were confused. See {@link #aliases(Map)} for more explanation.
+     */
+    private static final short[][] PARAMETER_ALIASES = {
+        {GeoKeys.NatOriginLong, GeoKeys.FalseOriginLong,     GeoKeys.CenterLong},
+        {GeoKeys.NatOriginLat,  GeoKeys.FalseOriginLat,      GeoKeys.CenterLat},
+        {GeoKeys.FalseEasting,  GeoKeys.FalseOriginEasting,  GeoKeys.CenterEasting},
+        {GeoKeys.FalseNorthing, GeoKeys.FalseOriginNorthing, GeoKeys.CenterNorthing},
+        {GeoKeys.ScaleAtNatOrigin,                           GeoKeys.ScaleAtCenter}
+    };
+
+    /**
+     * Updates a mapping from GeoTIFF numerical identifiers to parameter names by adding parameter aliases.
+     * This method adds to the given map some GeoTIFF keys to be considered synonymous to an existing key.
+     * Those "synonymous" parameters are strictly speaking not for the map projection that we are parsing,
+     * but it is common to see GeoTIFF files with "wrong" projection parameter codes. For example:
+     *
+     * <ul>
+     *   <li>The {@code "CT_LambertConfConic_1SP"} projection uses a {@code "NatOriginLong"} parameter.</li>
+     *   <li>The {@code "CT_LambertConfConic_2SP"} projection uses a {@code "FalseOriginLong"} parameter.</li>
+     * </ul>
+     *
+     * but we sometime see {@code "NatOriginLong"} parameter used for the {@code "CT_LambertConfConic_2SP"} projection.
+     * Semantically those two parameters are for two different things but mathematically they are used in the same way.
+     * Those "synonymous" will be invisible to the user; the map projection that (s)he will get uses the names defined
+     * in the descriptor (not in the GeoTIFF file).
+     */
+    private static void aliases(final Map<Integer,String> mapping) {
+        for (final short[] codes : PARAMETER_ALIASES) {
+            for (int i=0; i<codes.length; i++) {
+                final String name = mapping.get(codes[i] & 0xFFFF);
+                if (name != null) {
+                    for (int j=0; j<codes.length; j++) {
+                        if (j != i) {
+                            JDK8.putIfAbsent(mapping, codes[j] & 0xFFFF, name);
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
      * Creates a projected CRS from an EPSG code or from user-defined parameters.
      * Some GeoTIFF values used by this method are:
      *
@@ -1379,6 +1443,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.ProjectedCSType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.ProjectedCSType));
             }
             case GeoCodes.userDefined: {
@@ -1442,6 +1507,7 @@ final class CRSBuilder {
      * @param  linearUnit   the linear unit of easting and northing values.
      * @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 ParameterNotFoundException if the GeoTIFF file defines an unexpected map projection parameter.
      * @throws ClassCastException if an object defined by an EPSG code is not of the expected type.
      * @throws FactoryException if an error occurred during objects creation with the factories.
      */
@@ -1451,18 +1517,22 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.Projection);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.Projection));
             }
             case GeoCodes.userDefined: {
                 final Unit<Angle>         azimuthUnit = createUnit(GeoKeys.AzimuthUnits, (short) 0, Angle.class, Units.DEGREE);
                 final String              type        = getMandatoryString(GeoKeys.CoordTrans);
-                final OperationMethod     method      = operationFactory().getOperationMethod(type);
+                final OperationMethod     method      = operationFactory().getOperationMethod(Constants.GEOTIFF + ':' + type);
                 final ParameterValueGroup parameters  = method.getParameters().createValue();
+                final Map<Integer,String> toNames     = ReferencingUtilities.identifierToName(parameters.getDescriptor(), Citations.GEOTIFF);
+                final Map<Object,Number>  paramValues = new HashMap<>();    // Keys: [String|Short] instances for [known|unknown] parameters.
+                final Map<Short,Unit<?>>  deferred    = new HashMap<>();    // Only unknown parameters.
                 final Iterator<Map.Entry<Short,Object>> it = geoKeys.entrySet().iterator();
                 while (it.hasNext()) {
                     final Unit<?> unit;
                     final Map.Entry<Short,?> entry = it.next();
-                    final short key = entry.getKey();
+                    final Short key = entry.getKey();
                     switch (GeoKeys.unitOf(key)) {
                         case GeoKeys.RATIO:   unit = Units.UNITY; break;
                         case GeoKeys.LINEAR:  unit = linearUnit;  break;
@@ -1470,15 +1540,52 @@ final class CRSBuilder {
                         case GeoKeys.AZIMUTH: unit = azimuthUnit; break;
                         default: continue;
                     }
-                    final double value = ((Number) entry.getValue()).doubleValue();
+                    final Number value = (Number) entry.getValue();
                     it.remove();
-                    parameters.parameter("GeoTIFF:" + key).setValue(value, unit);
+                    final String paramName = toNames.get(key & 0xFFFF);
+                    if (paramName != null) {
+                        paramValues.put(paramName, value);
+                        parameters.parameter(paramName).setValue(value.doubleValue(), unit);
+                    } else {
+                        paramValues.put(key, value);
+                        deferred.put(key, unit);
+                    }
+                }
+                /*
+                 * At this point we finished to set all known map projection parameters. Sometime GeoTIFF files
+                 * set the same parameter many times using different names as a safety for GeoTIFF readers that
+                 * expect wrong parameters. If this is the case, verify that the parameter values are consistent.
+                 * It is also possible that we found new parameters (actually parameters using the wrong names).
+                 */
+                if (!deferred.isEmpty()) {
+                    aliases(toNames);
+                    for (final Map.Entry<Short,Unit<?>> entry : deferred.entrySet()) {
+                        final Short key = entry.getKey();
+                        String paramName = toNames.get(key & 0xFFFF);
+                        if (paramName == null) {
+                            paramName = GeoKeys.name(key);
+                            throw new ParameterNotFoundException(reader.errors().getString(
+                                    Errors.Keys.UnexpectedParameter_1, paramName), paramName);
+                        }
+                        final Number value  = paramValues.get(key);
+                        final Number actual = JDK8.putIfAbsent(paramValues, paramName, value);
+                        if (actual == null) {
+                            parameters.parameter(paramName).setValue(value.doubleValue(), entry.getValue());
+                        } else if (!actual.equals(value)) {
+                            warning(Resources.Keys.InconsistentMapProjParameter_4, paramName, actual, GeoKeys.name(key), value);
+                        }
+                    }
                 }
                 final Conversion c = operationFactory().createDefiningConversion(properties(name), method, parameters);
                 lastName = c.getName();
                 return c;
             }
             default: {
+                /*
+                 * Conversion defined by EPSG code. In principle we should just use the EPSG code.
+                 * But if the file also defines the components, verify that those components are
+                 * consistent with what we would expect for a conversion of the given EPSG code.
+                 */
                 final Conversion projection = (Conversion) epsgFactory().createCoordinateOperation(String.valueOf(epsg));
                 verify(projection, angularUnit, linearUnit);
                 return projection;
@@ -1551,6 +1658,7 @@ final class CRSBuilder {
         switch (epsg) {
             case GeoCodes.undefined:
             case GeoCodes.userDefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.VerticalDatum));
             }
             default: {

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -33,6 +33,7 @@ import org.apache.sis.storage.DataStoreC
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.internal.storage.MetadataBuilder;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.metadata.sql.MetadataStoreException;
 import org.apache.sis.storage.DataStoreClosedException;
 import org.apache.sis.util.resources.Errors;
@@ -107,7 +108,7 @@ public class GeoTiffStore extends DataSt
             final Reader reader = reader();
             final MetadataBuilder builder = reader.metadata;
             try {
-                builder.setFormat("GeoTIFF");
+                builder.setFormat(Constants.GEOTIFF);
             } catch (MetadataStoreException e) {
                 warning(null, e);
             }
@@ -136,7 +137,7 @@ public class GeoTiffStore extends DataSt
     private Reader reader() throws DataStoreException {
         final Reader r = reader;
         if (r == null) {
-            throw new DataStoreClosedException(getLocale(), "GeoTIFF", StandardOpenOption.READ);
+            throw new DataStoreClosedException(getLocale(), Constants.GEOTIFF, StandardOpenOption.READ);
         }
         return r;
     }

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java [UTF-8] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -26,6 +26,7 @@ import org.apache.sis.storage.ProbeResul
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.storage.Capabilities;
 import org.apache.sis.internal.storage.Capability;
+import org.apache.sis.internal.util.Constants;
 
 
 /**
@@ -69,7 +70,7 @@ public class GeoTiffStoreProvider extend
      */
     @Override
     public String getShortName() {
-        return "GeoTIFF";
+        return Constants.GEOTIFF;
     }
 
     /**

Modified: sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] (original)
+++ sis/trunk/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -28,7 +28,9 @@ import javax.measure.Unit;
 import javax.measure.quantity.Length;
 import org.opengis.metadata.citation.DateType;
 import org.opengis.util.FactoryException;
-import org.apache.sis.internal.jdk8.JDK8;
+import org.opengis.util.NoSuchIdentifierException;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.internal.geotiff.Resources;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.storage.DataStoreException;
@@ -37,6 +39,9 @@ import org.apache.sis.internal.storage.M
 import org.apache.sis.math.Vector;
 import org.apache.sis.measure.Units;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+
 
 /**
  * An Image File Directory (FID) in a TIFF image.
@@ -1035,10 +1040,16 @@ final class ImageFileDirectory {
             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.
+            } catch (NoSuchIdentifierException | ParameterNotFoundException e) {
+                short key = Resources.Keys.UnsupportedProjectionMethod_1;
+                if (e instanceof NoSuchAuthorityCodeException) {
+                    key = Resources.Keys.UnknownCRS_1;
+                }
+                reader.owner.warning(reader.resources().getString(key, reader.owner.getDisplayName()), e);
+            } catch (IllegalArgumentException | NoSuchElementException | ClassCastException e) {
+                if (!helper.alreadyReported) {
+                    reader.owner.warning(null, e);
+                }
             }
             geoKeyDirectory      = null;            // Not needed anymore, so let GC do its work.
             numericGeoParameters = null;

Modified: sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java [UTF-8] (original)
+++ sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -20,10 +20,13 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
+import java.util.HashMap;
 import com.esri.core.geometry.Point;
 import org.opengis.util.ScopedName;
+import org.opengis.util.GenericName;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
+import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.OnlineResource;
 import org.opengis.metadata.content.ContentInformation;
 import org.apache.sis.storage.gps.Fix;
@@ -33,10 +36,12 @@ import org.apache.sis.referencing.Common
 import org.apache.sis.feature.AbstractIdentifiedType;
 import org.apache.sis.feature.FeatureOperations;
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.feature.builder.PropertyTypeBuilder;
 import org.apache.sis.feature.builder.AttributeRole;
 import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.internal.storage.FeatureCatalogBuilder;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.util.iso.ResourceInternationalString;
 import org.apache.sis.util.iso.DefaultNameFactory;
 import org.apache.sis.util.Static;
 
@@ -108,6 +113,7 @@ final class Types extends Static {
      * @throws FactoryException if an error occurred while creating an "envelope bounds" operation.
      */
     Types(final NameFactory factory, final Locale locale) throws FactoryException, IllegalNameException {
+        final Map<String,InternationalString[]> resources = new HashMap<>();
         final ScopedName    geomName = AttributeConvention.GEOMETRY_PROPERTY;
         final Map<String,?> geomInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, geomName);
         final Map<String,?> envpInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, AttributeConvention.ENVELOPE_PROPERTY);
@@ -179,7 +185,7 @@ final class Types extends Static {
         builder.addAttribute(Double        .class).setName(Tags.PDOP);
         builder.addAttribute(Double        .class).setName(Tags.AGE_OF_GPS_DATA);
         builder.addAttribute(Integer       .class).setName(Tags.DGPS_ID);
-        wayPoint = builder.build();
+        wayPoint = create(builder, resources);
         /*
          * Route \u21fe GPXEntity
          * \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
@@ -212,7 +218,7 @@ final class Types extends Static {
         builder.addAttribute(Integer.class).setName(Tags.NUMBER);
         builder.addProperty(wayPoint.getProperty(Tags.TYPE));
         builder.addAssociation(wayPoint).setName(Tags.ROUTE_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
-        route = builder.build();
+        route = create(builder, resources);
         /*
          * TrackSegment \u21fe GPXEntity
          * \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
@@ -231,7 +237,7 @@ final class Types extends Static {
         builder.addProperty(FeatureOperations.envelope(envpInfo, null, groupOp));
         builder.setDefaultCardinality(0, 1);
         builder.addAssociation(wayPoint).setName(Tags.TRACK_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
-        trackSegment = builder.build();
+        trackSegment = create(builder, resources);
         /*
          * Track \u21fe GPXEntity
          * \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
@@ -264,7 +270,7 @@ final class Types extends Static {
         builder.addProperty(route.getProperty(Tags.NUMBER));
         builder.addProperty(route.getProperty(Tags.TYPE));
         builder.addAssociation(trackSegment).setName(Tags.TRACK_SEGMENTS).setMaximumOccurs(Integer.MAX_VALUE);
-        track = builder.build();
+        track = create(builder, resources);
 
         final FeatureCatalogBuilder fc = new FeatureCatalogBuilder(null);
         fc.define(route);
@@ -273,4 +279,32 @@ final class Types extends Static {
         metadata = fc.build(true).getContentInfo();
         names = fc.features;
     }
+
+    /**
+     * Adds internationalized designation and definition information for all properties in the given type.
+     * Then, returns the result of {@link FeatureTypeBuilder#build()}.
+     *
+     * @param  builder   the feature type builder for which to add designations and definitions.
+     * @param  previous  previously created international strings as array of length 2.
+     *                   The first element is the designation and the second element is the definition.
+     */
+    private static DefaultFeatureType create(final FeatureTypeBuilder builder, final Map<String,InternationalString[]> previous) {
+        for (final PropertyTypeBuilder p : builder.properties()) {
+            final GenericName name = p.getName();
+            if (!AttributeConvention.contains(name)) {
+                final String key = name.toString();
+                InternationalString[] resources = previous.get(key);
+                if (resources == null) {
+                    resources = new InternationalString[] {
+                        new ResourceInternationalString("org.apache.sis.internal.storage.gpx.Designations", key),
+                        new ResourceInternationalString("org.apache.sis.internal.storage.gpx.Definitions",  key)
+                    };
+                    previous.put(key, resources);
+                }
+                p.setDefinition (resources[1]);
+                p.setDesignation(resources[0]);
+            }
+        }
+        return builder.build();
+    }
 }

Modified: sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/MetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/MetadataTest.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/MetadataTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/MetadataTest.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -19,6 +19,7 @@ package org.apache.sis.internal.storage.
 import java.util.Arrays;
 import java.net.URI;
 import java.net.URISyntaxException;
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -37,6 +38,7 @@ import static org.apache.sis.test.TestUt
  * @since   0.8
  * @module
  */
+@DependsOn(TypesTest.class)
 public final strictfp class MetadataTest extends TestCase {
     /**
      * Tests the {@link Metadata#equals(Object)} and {@link Metadata#hashCode()}.

Copied: sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java (from r1792304, sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java)
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java?p2=sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java&p1=sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java&r1=1792304&r2=1792306&rev=1792306&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TypesTest.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -27,8 +27,8 @@ import org.junit.Test;
 import static org.junit.Assert.*;
 
 // Branch-dependent imports
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
+import org.apache.sis.feature.DefaultFeatureType;
+import org.apache.sis.feature.AbstractIdentifiedType;
 
 
 /**
@@ -58,8 +58,8 @@ public final strictfp class TypesTest ex
     /**
      * Verifies that all designations and definitions can be read from the resources.
      */
-    private static void testResources(final FeatureType type) {
-        for (final PropertyType p : type.getProperties(false)) {
+    private static void testResources(final DefaultFeatureType type) {
+        for (final AbstractIdentifiedType p : type.getProperties(false)) {
             final GenericName name = p.getName();
             if (!AttributeConvention.contains(name)) {
                 final String label = name.toString();

Modified: sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/test/suite/GPXTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/test/suite/GPXTestSuite.java?rev=1792306&r1=1792305&r2=1792306&view=diff
==============================================================================
--- sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/test/suite/GPXTestSuite.java [UTF-8] (original)
+++ sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/test/suite/GPXTestSuite.java [UTF-8] Sat Apr 22 17:17:54 2017
@@ -25,6 +25,7 @@ import org.junit.BeforeClass;
  * All tests from the {@code sis-xmlstore} module, in approximative dependency order.
  */
 @Suite.SuiteClasses({
+    org.apache.sis.internal.storage.gpx.TypesTest.class,
     org.apache.sis.internal.storage.gpx.MetadataTest.class,
     org.apache.sis.internal.storage.gpx.ReaderTest.class,
     org.apache.sis.internal.storage.gpx.WriterTest.class