sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1773585 - in /sis/branches/JDK8: ide-project/NetBeans/nbproject/ storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/ storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/
Date Sun, 11 Dec 2016 16:14:11 GMT
Author: desruisseaux
Date: Sun Dec 11 16:14:11 2016
New Revision: 1773585

URL: http://svn.apache.org/viewvc?rev=1773585&view=rev
Log:
Add GeocentricCRS and VerticalCRS case in GeoTIFF reader.

Modified:
    sis/branches/JDK8/ide-project/NetBeans/nbproject/cfg_hints.xml
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
    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/GeoTiffStoreProvider.java

Modified: sis/branches/JDK8/ide-project/NetBeans/nbproject/cfg_hints.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/ide-project/NetBeans/nbproject/cfg_hints.xml?rev=1773585&r1=1773584&r2=1773585&view=diff
==============================================================================
--- sis/branches/JDK8/ide-project/NetBeans/nbproject/cfg_hints.xml (original)
+++ sis/branches/JDK8/ide-project/NetBeans/nbproject/cfg_hints.xml Sun Dec 11 16:14:11 2016
@@ -142,5 +142,13 @@
         <node name="org.netbeans.modules.java.hints.jdk.ThrowableInitCause">
             <attribute name="strict" value="false"/>
         </node>
+        <node name="org.netbeans.modules.java.hints.suggestions.ConstantNameHint">
+            <attribute name="immutableClasses" value=""/>
+            <attribute name="namePattern" value="[A-Z]([A-Z\d_]*[A-Z\d])?"/>
+            <attribute name="minLength" value="0"/>
+            <attribute name="onlyCheckImmutables" value="true"/>
+            <attribute name="maxLength" value="35"/>
+            <attribute name="enabled" value="false"/>
+        </node>
     </tool>
 </configuration>

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java?rev=1773585&r1=1773584&r2=1773585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
[UTF-8] Sun Dec 11 16:14:11 2016
@@ -88,9 +88,9 @@ public final class Resources extends Ind
         public static final short DitheringOrHalftoningApplied_2 = 3;
 
         /**
-         * The “{0}” GeoTIFF key has been ignored.
+         * The following GeoTIFF keys have been ignored: {0}
          */
-        public static final short IgnoredGeoKey_1 = 16;
+        public static final short IgnoredGeoKeys_1 = 19;
 
         /**
          * The “{0}” TIFF tag has been ignored.
@@ -129,8 +129,8 @@ public final class Resources extends Ind
         public static final short MissingValue_2 = 7;
 
         /**
-         * The file defines “{2}” with a value of {3}{4}, but that value should be {1}{4}
according
-         * parent definition ({0}).
+         * The file defines “{2}” with value {3}{4}, but that value should be {1}{4}
according parent
+         * definition ({0}).
          */
         public static final short NotTheEpsgValue_5 = 17;
 
@@ -145,6 +145,11 @@ public final class Resources extends Ind
         public static final short UnexpectedListOfValues_2 = 15;
 
         /**
+         * The “{1}” parameter was not expected for the “{0}” projection method.
+         */
+        public static final short UnexpectedParameter_2 = 20;
+
+        /**
          * Found {2} tiles or strips in the “{0}” file while {1} were expected.
          */
         public static final short UnexpectedTileCount_3 = 10;
@@ -158,6 +163,11 @@ public final class Resources extends Ind
          * Version {0} of GeoTIFF key directory is not supported.
          */
         public static final short UnsupportedGeoKeyDirectory_1 = 13;
+
+        /**
+         * Unsupported storage location for the “{0}” GeoTIFF value.
+         */
+        public static final short UnsupportedGeoKeyStorage_1 = 16;
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties?rev=1773585&r1=1773584&r2=1773585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
[ISO-8859-1] Sun Dec 11 16:14:11 2016
@@ -25,16 +25,18 @@ ComputedValueForAttribute_2       = No v
 DefaultValueForAttribute_2        = No value specified for the \u201c{0}\u201d TIFF tag.
The {1} default value will be used.
 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.
-IgnoredGeoKey_1                   = The \u201c{0}\u201d GeoTIFF key has been ignored.
+IgnoredGeoKeys_1                  = The following GeoTIFF keys have been ignored: {0}
 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}.
 MismatchedLength_4                = TIFF tags \u201c{0}\u201d and \u201c{1}\u201d have values
of different lengths. Found \u201c{2}\u201d and \u201c{3}\u201d elements respectively.
 MissingGeoValue_1                 = No value has been found for the \u201c{0}\u201d GeoTIFF
key.
 MissingValue_2                    = Can not read TIFF image from \u201c{0}\u201d because
the \u201c{1}\u201d tag is missing.
-NotTheEpsgValue_5                 = The file defines \u201c{2}\u201d with a value of {3}{4},
but that value should be {1}{4} according parent definition ({0}).
+NotTheEpsgValue_5                 = The file defines \u201c{2}\u201d with value {3}{4}, but
that value should be {1}{4} according parent definition ({0}).
 RandomizedProcessApplied          = A randomized process such as error diffusion has been
applied to the image data.
 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.
 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.

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties?rev=1773585&r1=1773584&r2=1773585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
[ISO-8859-1] Sun Dec 11 16:14:11 2016
@@ -30,7 +30,7 @@ ComputedValueForAttribute_2       = Aucu
 DefaultValueForAttribute_2        = Aucune valeur n\u2019a \u00e9t\u00e9 sp\u00e9cifi\u00e9e
pour le tag TIFF \u00ab\u202f{0}\u202f\u00bb. La valeur par d\u00e9faut sera {1}.
 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.
-IgnoredGeoKey_1                   = La cl\u00e9 GeoTIFF \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9
ignor\u00e9e.
+IgnoredGeoKeys_1                  = Les cl\u00e9s GeoTIFF suivantes ont \u00e9t\u00e9 ignor\u00e9es\u2008:
{0}
 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}.
@@ -40,6 +40,8 @@ MissingValue_2                    = Ne p
 NotTheEpsgValue_5                 = Le fichier d\u00e9finit \u00ab\u202f{2}\u202f\u00bb avec
la valeur {3}{4}, mais cette valeur devrait \u00eatre {1}{4} pour \u00eatre en accord avec
la d\u00e9finition du parent {0}.
 RandomizedProcessApplied          = Un processus randomis\u00e9 comme la diffusion d\u2019erreur
a \u00e9t\u00e9 appliqu\u00e9.
 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}.
 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.

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=1773585&r1=1773584&r2=1773585&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] Sun Dec 11 16:14:11 2016
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.storage.geotiff;
 
+import java.util.Arrays;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -36,16 +37,21 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.spatial.CellGeometry;
 import org.opengis.metadata.spatial.PixelOrientation;
 import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.cs.VerticalCS;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.PrimeMeridian;
+import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.operation.Conversion;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
@@ -65,6 +71,7 @@ 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,7 +87,6 @@ import org.apache.sis.util.Characters;
 import org.apache.sis.util.Debug;
 
 import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
-import org.apache.sis.util.iso.DefaultNameSpace;
 
 
 /**
@@ -192,6 +198,9 @@ final class CRSBuilder {
 
     /**
      * All values found in the {@code GeoKeyDirectory} after the header.
+     * Each value shall be used at most once. This allow us to remove value after usage,
+     * so we can easily detect at the end of the parsing process which GeoTIFF keys were
+     * unrecognized or ignored.
      */
     private final Map<Short,Object> geoKeys = new HashMap<>();
 
@@ -524,9 +533,14 @@ final class CRSBuilder {
     }
 
 
-    // ---------------------------- geokeys parsing -----------------------------
 
 
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                            
     ////////
+    ////////                                 GeoKeys parsing                            
     ////////
+    ////////                                                                            
     ////////
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+
     /**
      * Decodes all the given GeoTIFF keys, then creates a coordinate reference system.
      * An overview of the key directory structure is given in {@linkplain CRSBuilder class
javadoc}.
@@ -672,29 +686,39 @@ final class CRSBuilder {
                  * it would have be stored in one of the standard GeoTIFF tags.
                  */
                 default: {
-                    warning(Resources.Keys.IgnoredGeoKey_1, GeoKeys.name(key));
+                    warning(Resources.Keys.UnsupportedGeoKeyStorage_1, GeoKeys.name(key));
                     continue;
                 }
             }
             geoKeys.put(key, value);
         }
         /*
-         * At this point we finished copying all GeoTIFF keys in CRSBuilder.geoKeys map.
+         * At this point we finished copying all GeoTIFF keys in 'CRSBuilder.geoKeys' map.
+         * First create the main coordinate reference system, as determined by 'ModelType'.
+         * Then if a vertical CRS exists and the main CRS is not geocentric (in which case
+         * adding a vertical CRS would make no sense), create a three-dimensional compound
CRS.
          */
+        CoordinateReferenceSystem crs;
         final int crsType = getAsInteger(GeoKeys.ModelType);
         switch (crsType) {
             case GeoCodes.undefined:           return null;
-            case GeoCodes.ModelTypeProjected:  return createProjectedCRS();
+            case GeoCodes.ModelTypeProjected:  crs = createProjectedCRS(); break;
+            case GeoCodes.ModelTypeGeocentric: return createGeocentricCRS();        // Ignore
vertical CRS.
             case GeoCodes.ModelTypeGeographic: {
-                return createGeographicCRS(true,
+                crs = createGeographicCRS(true,
                         createUnit(GeoKeys.AngularUnits, GeoKeys.AngularUnitSize, Angle.class,
Units.DEGREE));
+                break;
             }
-            case GeoCodes.ModelTypeGeocentric: // TODO
             default: {
                 warning(Resources.Keys.UnsupportedCoordinateSystemKind_1, crsType);
                 return null;
             }
         }
+        final VerticalCRS vertical = createVerticalCRS();
+        if (vertical != null) {
+            crs = objectFactory().createCompoundCRS(Collections.singletonMap(IdentifiedObject.NAME_KEY,
crs.getName()), crs, vertical);
+        }
+        return crs;
     }
 
     /**
@@ -707,6 +731,8 @@ final class CRSBuilder {
      *   <li>{@link ImageFileDirectory} must have filled its part of metadata before
to invoke this method.</li>
      * </ul>
      *
+     * After execution, this method emits a warning for unprocessed GeoTIFF tags.
+     *
      * @param  metadata  the helper class where to write metadata values.
      * @throws NumberFormatException if a numeric value was stored as a string and can not
be parsed.
      */
@@ -737,12 +763,36 @@ final class CRSBuilder {
         }
         metadata.setCellGeometry(cg);
         metadata.setPointInPixel(po);
+        /*
+         * Build a list of remaining GeoKeys.
+         */
+        if (!geoKeys.isEmpty()) {
+            final StringJoiner joiner = new StringJoiner(", ");
+            for (final short key : remainingKeys()) {
+                joiner.add(GeoKeys.name(key));
+            }
+            warning(Resources.Keys.IgnoredGeoKeys_1, joiner.toString());
+        }
+    }
+
+    /**
+     * Returns all remaining keys, sorted in increasing order.
+     */
+    private Short[] remainingKeys() {
+        final Short[] keys = geoKeys.keySet().toArray(new Short[geoKeys.size()]);
+        Arrays.sort(keys);
+        return keys;
     }
 
 
-    // -------------------------- geodetic components ---------------------------
 
 
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                            
     ////////
+    ////////                   Geodetic components (datum, ellipsoid, etc.)             
     ////////
+    ////////                                                                            
     ////////
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+
     /**
      * Returns a coordinate system (CS) with the same axis directions than the given CS but
potentially different units.
      * If a coordinate system exists in the EPSG database with the requested characteristics,
that CS will be returned
@@ -851,7 +901,9 @@ final class CRSBuilder {
     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.undefined: {
+                break;                      // If not specified, default to Greenwich.
+            }
             case GeoCodes.userDefined: {
                 final double longitude = getAsDouble(GeoKeys.PrimeMeridianLong);
                 if (Double.isNaN(longitude)) {
@@ -865,7 +917,7 @@ final class CRSBuilder {
                      */
                     return objectFactory().createPrimeMeridian(properties(names[PRIMEM]),
longitude, unit);
                 }
-                break;              // Default to Greenwich.
+                break;                      // Default to Greenwich.
             }
             default: {
                 /*
@@ -1064,9 +1116,14 @@ final class CRSBuilder {
     }
 
 
-    // ----------------------------- geographic CRS -----------------------------
 
 
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                            
     ////////
+    ////////                     Geodetic CRS (geographic and geocentric)               
     ////////
+    ////////                                                                            
     ////////
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+
     /**
      * 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:
@@ -1216,9 +1273,80 @@ final class CRSBuilder {
         verify(datum, angularUnit, linearUnit);
     }
 
+    /**
+     * Creates a geocentric CRS from user-defined parameters.
+     * The GeoTIFF values used by this method are the same than the ones used by {@code createGeographicCRS(…)}.
+     *
+     * @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 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.
+     *
+     * @see #createGeodeticDatum(String, Unit, Unit)
+     */
+    private GeocentricCRS createGeocentricCRS() throws FactoryException {
+        final int epsg = getAsInteger(GeoKeys.GeographicType);
+        switch (epsg) {
+            case GeoCodes.undefined: {
+                throw new NoSuchElementException(missingValue(GeoKeys.GeographicType));
+            }
+            case GeoCodes.userDefined: {
+                /*
+                 * Creates the geodetic datum, then a geocentric CRS. We use the coordinate
system of
+                 * the WGS84 geocentric CRS as a template and modify its unit of measurement
if needed.
+                 */
+                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);
+                CartesianCS cs = (CartesianCS) CommonCRS.WGS84.geocentric().getCoordinateSystem();
+                if (!Units.METRE.equals(linearUnit)) {
+                    cs = replaceLinearUnit(cs, linearUnit);
+                }
+                final GeocentricCRS crs = objectFactory().createGeocentricCRS(properties(getOrDefault(names,
GCRS)), datum, cs);
+                lastName = crs.getName();
+                return crs;
+            }
+            default: {
+                /*
+                 * Geocentric CRS defined by an 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 CRS of the given EPSG code.
+                 */
+                final GeocentricCRS crs = epsgFactory().createGeocentricCRS(String.valueOf(epsg));
+                verify(crs);
+                return crs;
+            }
+        }
+    }
+
+    /**
+     * Verifies if the user-defined CRS created from GeoTIFF values
+     * matches the given CRS created from the EPSG geodetic dataset.
+     * This method does not verify the EPSG code of the given CRS.
+     *
+     * @param  crs  the CRS created from the EPSG geodetic dataset.
+     */
+    private void verify(final GeocentricCRS crs) throws FactoryException {
+        /*
+         * 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.AngularUnits, GeoKeys.AngularUnitSize,
Angle.class, Units.DEGREE);
+        final GeodeticDatum datum = crs.getDatum();
+        verifyIdentifier(crs, datum, GeoKeys.GeodeticDatum);
+        verify(datum, angularUnit, linearUnit);
+    }
+
+
 
-    // ----------------------------- projected CRS ------------------------------
 
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                            
     ////////
+    ////////                                  Projected CRS                             
     ////////
+    ////////                                                                            
     ////////
+    //////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
      * Creates a projected CRS from an EPSG code or from user-defined parameters.
@@ -1330,17 +1458,17 @@ final class CRSBuilder {
                 while (it.hasNext()) {
                     final Unit<?> unit;
                     final Map.Entry<Short,?> entry = it.next();
-                    final short code = entry.getKey();
-                    switch (GeoKeys.unitOf(code)) {
-                        case GeoKeys.RATIO:     unit = Units.UNITY; break;
-                        case GeoKeys.LINEAR:    unit = linearUnit;  break;
-                        case GeoKeys.ANGULAR:   unit = angularUnit; break;
-                        case GeoKeys.AZIMUTH:   unit = azimuthUnit; break;
+                    final short key = entry.getKey();
+                    switch (GeoKeys.unitOf(key)) {
+                        case GeoKeys.RATIO:   unit = Units.UNITY; break;
+                        case GeoKeys.LINEAR:  unit = linearUnit;  break;
+                        case GeoKeys.ANGULAR: unit = angularUnit; break;
+                        case GeoKeys.AZIMUTH: unit = azimuthUnit; break;
                         default: continue;
                     }
                     final double value = ((Number) entry.getValue()).doubleValue();
                     it.remove();
-                    parameters.parameter("GeoTIFF" + code).setValue(value, unit);
+                    parameters.parameter("GeoTIFF:" + key).setValue(value, unit);
                 }
                 final Conversion c = operationFactory().createDefiningConversion(properties(name),
method, parameters);
                 lastName = c.getName();
@@ -1364,7 +1492,108 @@ final class CRSBuilder {
     private void verify(final Conversion projection, final Unit<Angle> angularUnit,
final Unit<Length> linearUnit)
             throws FactoryException
     {
-        // TODO
+        final Unit<Angle> azimuthUnit = createUnit(GeoKeys.AzimuthUnits, (short) 0,
Angle.class, Units.DEGREE);
+        final String type = getAsString(GeoKeys.CoordTrans);
+        if (type != null) {
+            /*
+             * Compare the name of the map projection declared in the GeoTIFF file with the
name
+             * of the projection used by the EPSG geodetic dataset.
+             */
+            final OperationMethod method = projection.getMethod();
+            if (!IdentifiedObjects.isHeuristicMatchForName(method, type)) {
+                Identifier expected = IdentifiedObjects.getIdentifier(method, Citations.GEOTIFF);
+                if (expected == null) {
+                    expected = IdentifiedObjects.getIdentifier(method, null);
+                }
+                warning(Resources.Keys.NotTheEpsgValue_5, IdentifiedObjects.getIdentifierOrName(projection),
+                        expected.getCode(), GeoKeys.name(GeoKeys.CoordTrans), type, "");
+            }
+            /*
+             * Compare the parameter values with the ones declared in the EPSG geodetic dataset.
+             */
+            final ParameterValueGroup parameters = projection.getParameterValues();
+            for (final short key : remainingKeys()) {
+                final Unit<?> unit;
+                switch (GeoKeys.unitOf(key)) {
+                    case GeoKeys.RATIO:   unit = Units.UNITY; break;
+                    case GeoKeys.LINEAR:  unit = linearUnit;  break;
+                    case GeoKeys.ANGULAR: unit = angularUnit; break;
+                    case GeoKeys.AZIMUTH: unit = azimuthUnit; break;
+                    default: continue;
+                }
+                try {
+                    verify(projection, parameters.parameter("GeoTIFF:" + key).doubleValue(unit),
key, unit);
+                } catch (ParameterNotFoundException e) {
+                    warning(Resources.Keys.UnexpectedParameter_2, type, GeoKeys.name(key));
+                }
+            }
+        }
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                            
     ////////
+    ////////                                   Vertical CRS                             
     ////////
+    ////////                                                                            
     ////////
+    //////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Creates a vertical datum.
+     */
+    private VerticalDatum createVerticalDatum() throws FactoryException {
+        final int epsg = getAsInteger(GeoKeys.VerticalDatum);
+        switch (epsg) {
+            case GeoCodes.undefined:
+            case GeoCodes.userDefined: {
+                throw new NoSuchElementException(missingValue(GeoKeys.VerticalDatum));
+            }
+            default: {
+                return epsgFactory().createVerticalDatum(String.valueOf(epsg));
+            }
+        }
+    }
+
+    /**
+     * Creates an optional vertical CRS, or returns {@code null} if no vertical CRS definition
is found.
+     * This method is different from the other {@code createFooCRS()} methods in that the
vertical CRS
+     * may be defined <em>in addition</em> of another CRS. Some GeoTIFF values
used by this method are:
+     *
+     * <ul>
+     *   <li>A code given by {@link GeoKeys#VerticalCSType}.</li>
+     *   <li>If above code is {@link GeoCodes#userDefined}, then:<ul>
+     *     <li>a name given by {@link GeoKeys#VerticalCitation},</li>
+     *     <li>a {@link VerticalDatum} given by {@link GeoKeys#VerticalDatum}.</li>
+     *   </ul></li>
+     *   <li>A unit code given by {@link GeoKeys#VerticalUnits} (optional).</li>
+     * </ul>
+     *
+     * @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 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.
+     */
+    private VerticalCRS createVerticalCRS() throws FactoryException {
+        final int epsg = getAsInteger(GeoKeys.VerticalCSType);
+        switch (epsg) {
+            case GeoCodes.undefined: {
+                return null;
+            }
+            case GeoCodes.userDefined: {
+                final String name = getAsString(GeoKeys.VerticalCitation);
+                final VerticalDatum datum = createVerticalDatum();
+                final Unit<Length> unit = createUnit(GeoKeys.VerticalUnits, (short)
0, Length.class, Units.METRE);
+                VerticalCS cs = CommonCRS.Vertical.MEAN_SEA_LEVEL.crs().getCoordinateSystem();
+                if (!Units.METRE.equals(unit)) {
+                    cs = (VerticalCS) CoordinateSystems.replaceLinearUnit(cs, unit);
+                }
+                return objectFactory().createVerticalCRS(properties(name), datum, cs);
+            }
+            default: {
+                return epsgFactory().createVerticalCRS(String.valueOf(epsg));
+            }
+        }
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java?rev=1773585&r1=1773584&r2=1773585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
[UTF-8] Sun Dec 11 16:14:11 2016
@@ -18,6 +18,7 @@ package org.apache.sis.storage.geotiff;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import org.apache.sis.util.Version;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreProvider;
@@ -47,6 +48,11 @@ public class GeoTiffStoreProvider extend
     private static final String MIME_TYPE = "image/tiff";
 
     /**
+     * The TIFF version.
+     */
+    private static final Version VERSION = new Version("6.0");
+
+    /**
      * Creates a new provider.
      */
     public GeoTiffStoreProvider() {
@@ -78,7 +84,7 @@ public class GeoTiffStoreProvider extend
                     buffer.order(isBigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
                     switch (buffer.getShort(p + Short.BYTES)) {
                         case GeoTIFF.CLASSIC:
-                        case GeoTIFF.BIG_TIFF: return new ProbeResult(true, MIME_TYPE, null);
+                        case GeoTIFF.BIG_TIFF: return new ProbeResult(true, MIME_TYPE, VERSION);
                     }
                 } finally {
                     buffer.order(old);



Mime
View raw message