sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1782436 - in /sis/trunk: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-referencing/src/main/java/org/apache/sis/geometry/ core/sis-referencing/src/main/java/org/ap...
Date Fri, 10 Feb 2017 07:21:41 GMT
Author: desruisseaux
Date: Fri Feb 10 07:21:40 2017
New Revision: 1782436

URL: http://svn.apache.org/viewvc?rev=1782436&view=rev
Log:
Merge from the JDK7 branch.

Added:
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ZonedTransverseMercator.java
      - copied unchanged from r1782435, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ZonedTransverseMercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java
      - copied unchanged from r1782435, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ZonedGridSystemTest.java
      - copied unchanged from r1782435, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ZonedGridSystemTest.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/README
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
    sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/trunk/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
    sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java

Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Feb 10 07:21:40 2017
@@ -1,5 +1,5 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394364-1758914
-/sis/branches/JDK7:1394913-1781502
-/sis/branches/JDK8:1584960-1781501
+/sis/branches/JDK7:1394913-1782435
+/sis/branches/JDK8:1584960-1782434
 /sis/branches/JDK9:1773327-1773512

Modified: sis/trunk/README
URL: http://svn.apache.org/viewvc/sis/trunk/README?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/README (original)
+++ sis/trunk/README Fri Feb 10 07:21:40 2017
@@ -38,7 +38,7 @@ Information for running a command-line t
 License (see also LICENSE)
 ==========================
 
-Collective work: Copyright 2010-2016 The Apache Software Foundation.
+Collective work: Copyright 2010-2017 The Apache Software Foundation.
 
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -481,7 +481,7 @@ header: for (int i=0; ; i++) {
     @Override
     public Object parse(final CharSequence text, final ParsePosition pos) throws ParseException {
         throw new ParseException(Errors.getResources(displayLocale)
-                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), 0);
+                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), pos.getIndex());
     }
 
     /**

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -703,10 +703,12 @@ public class WKTFormat extends CompoundF
     /**
      * Creates an object from the given character sequence.
      * The parsing begins at the index given by the {@code pos} argument.
+     * After successful parsing, {@link ParsePosition#getIndex()} gives the position after the last parsed character.
+     * In case of error, {@link ParseException#getErrorOffset()} gives the position of the first illegal character.
      *
      * @param  wkt  the character sequence for the object to parse.
      * @param  pos  the position where to start the parsing.
-     * @return the parsed object.
+     * @return the parsed object (never {@code null}).
      * @throws ParseException if an error occurred while parsing the WKT.
      */
     @Override

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -565,25 +565,16 @@ public class CoordinateFormat extends Co
     /**
      * Parses a coordinate from the given character sequence.
      * This method presumes that the coordinate reference system is the {@linkplain #getDefaultCRS() default CRS}.
-     * The parsing begins at the index given by the {@code pos} argument. If parsing succeeds, then:
-     *
-     * <ul>
-     *   <li>The {@code pos} {@linkplain ParsePosition#getIndex() index}
-     *       is updated to the index after the last ordinate value.</li>
-     *   <li>The parsed coordinate is returned.</li>
-     * </ul>
-     *
-     * If parsing fails, then:
-     *
-     * <ul>
-     *   <li>The {@code pos} index is left unchanged</li>
-     *   <li>The {@code pos} {@linkplain ParsePosition#getErrorIndex() error index}
-     *       is set to the beginning of the unparsable ordinate value.</li>
-     * </ul>
+     * The parsing begins at the {@linkplain ParsePosition#getIndex() index} given by the {@code pos} argument.
+     * If parsing succeeds, then the {@code pos} index is updated to the index after the last ordinate value and
+     * the parsed coordinate is returned. Otherwise (if parsing fails), the {@code pos} index is left unchanged,
+     * the {@code pos} {@linkplain ParsePosition#getErrorIndex() error index} is set to the index of the first
+     * unparsable character and an exception is thrown with a similar {@linkplain ParseException#getErrorOffset()
+     * error index}.
      *
      * @param  text  the character sequence for the coordinate to parse.
      * @param  pos   the index where to start the parsing.
-     * @return the parsed coordinate.
+     * @return the parsed coordinate (never {@code null}).
      * @throws ParseException if an error occurred while parsing the coordinate.
      */
     @Override

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -252,7 +252,7 @@ public class GeodeticObjectBuilder exten
         ArgumentChecks.ensureBetween("latitude",   Latitude.MIN_VALUE,     Latitude.MAX_VALUE,     latitude);
         ArgumentChecks.ensureBetween("longitude", -Formulas.LONGITUDE_MAX, Formulas.LONGITUDE_MAX, longitude);
         setConversionMethod(TransverseMercator.NAME);
-        setConversionName(TransverseMercator.setParameters(parameters, isUTM, latitude, longitude));
+        setConversionName(TransverseMercator.Zoner.UTM.setParameters(parameters, isUTM, latitude, longitude));
         return this;
     }
 

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -25,7 +25,9 @@ import org.apache.sis.parameter.Paramete
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.operation.projection.NormalizedProjection;
+import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.measure.Units;
 
@@ -49,14 +51,6 @@ public final class TransverseMercator ex
     private static final long serialVersionUID = -3386587506686432398L;
 
     /**
-     * Width of a Universal Transverse Mercator (UTM) zone, in degrees.
-     *
-     * @see #zone(double)
-     * @see #centralMeridian(int)
-     */
-    private static final double ZONE_WIDTH = 6;
-
-    /**
      * The {@value} string, which is also the EPSG name for this projection.
      */
     public static final String NAME = "Transverse Mercator";
@@ -138,79 +132,182 @@ public final class TransverseMercator ex
     }
 
     /**
-     * Sets the parameter values for a Transverse Mercator projection and returns a suggested conversion name.
-     *
-     * <blockquote><table class="sis">
-     *   <caption>Transverse Mercator parameters</caption>
-     *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
-     *   <tr><td>Latitude of natural origin</td>     <td>Given latitude, or 0° if UTM projection</td></tr>
-     *   <tr><td>Longitude of natural origin</td>    <td>Given longitude, optionally snapped to a UTM central meridian</td></tr>
-     *   <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr>
-     *   <tr><td>False easting</td>                  <td>500000 metres</td></tr>
-     *   <tr><td>False northing</td>                 <td>0 (North hemisphere) or 10000000 (South hemisphere) metres</td></tr>
-     * </table></blockquote>
-     *
-     * @param  group      the parameters for which to set the values.
-     * @param  isUTM      {@code true} for Universal Transverse Mercator (UTM) projection.
-     * @param  latitude   the latitude in the center of the desired projection.
-     * @param  longitude  the longitude in the center of the desired projection.
-     * @return a name like <cite>"Transverse Mercator"</cite> or <cite>"UTM zone 10N"</cite>,
-     *         depending on the arguments given to this method.
+     * Computes zone numbers and central meridian.
      *
-     * @since 0.7
-     */
-    public static String setParameters(final ParameterValueGroup group,
-            final boolean isUTM, double latitude, double longitude)
-    {
-        final boolean isSouth = MathFunctions.isNegative(latitude);
-        int zone = zone(longitude);
-        if (isUTM) {
-            latitude = 0;
-            longitude = centralMeridian(zone);
-        } else if (longitude != centralMeridian(zone)) {
-            zone = 0;
+     * @author  Martin Desruisseaux (Geomatys)
+     * @since   0.8
+     * @version 0.8
+     * @module
+     */
+    public static enum Zoner {
+        /**
+         * Computes zones for the Universal Transverse Mercator (UTM) projections.
+         *
+         * <blockquote><table class="sis">
+         *   <caption>Universal Transverse Mercator parameters</caption>
+         *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
+         *   <tr><td>Latitude of natural origin</td>     <td>0°</td></tr>
+         *   <tr><td>Longitude of natural origin</td>    <td>Given longitude snapped to a UTM central meridian</td></tr>
+         *   <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr>
+         *   <tr><td>False easting</td>                  <td>500000 metres</td></tr>
+         *   <tr><td>False northing</td>                 <td>0 (North hemisphere) or 10000000 (South hemisphere) metres</td></tr>
+         * </table></blockquote>
+         */
+        UTM(Longitude.MIN_VALUE, 6, 0.9996, 500000, 10000000),
+
+        /**
+         * Computes zones for the Modified Transverse Mercator (MTM) projections.
+         * This projection is in used in Canada only.
+         *
+         * <blockquote><table class="sis">
+         *   <caption>Modified Transverse Mercator parameters</caption>
+         *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
+         *   <tr><td>Latitude of natural origin</td>     <td>0°</td></tr>
+         *   <tr><td>Longitude of natural origin</td>    <td>Given longitude snapped to a MTM central meridian</td></tr>
+         *   <tr><td>Scale factor at natural origin</td> <td>0.9999</td></tr>
+         *   <tr><td>False easting</td>                  <td>304800 metres</td></tr>
+         *   <tr><td>False northing</td>                 <td>0 metres</td></tr>
+         * </table></blockquote>
+         */
+        MTM(-51.5, -3, 0.9999, 304800, Double.NaN);
+
+        /**
+         * Longitude of the beginning of zone 1. This is the westmost longitude if {@link #width} is positive,
+         * or the eastmost longitude if {@code width} is negative.
+         */
+        private final double origin;
+
+        /**
+         * Width of a zone, in degrees of longitude.
+         * Positive if zone numbers are increasing eastward, or negative if increasing westwards.
+         *
+         * @see #zone(double)
+         * @see #centralMeridian(int)
+         */
+        private final double width;
+
+        /**
+         * The scale factor of UTM projections.
+         */
+        private final double scale;
+
+        /**
+         * The false easting of UTM projections, in metres.
+         */
+        private final double easting;
+
+        /**
+         * The false northing in South hemisphere of UTM projection, in metres.
+         */
+        private final double northing;
+
+        /**
+         * Creates a new instance for computing zones using the given parameters.
+         */
+        private Zoner(final double origin, final double width, final double scale, final double easting, final double northing) {
+            this.origin   = origin;
+            this.width    = width;
+            this.scale    = scale;
+            this.easting  = easting;
+            this.northing = northing;
         }
-        String name = NAME;
-        if (zone != 0) {
-            name = "UTM zone " + zone + (isSouth ? 'S' : 'N');
+
+        /**
+         * Sets the parameter values for a Transverse Mercator projection and returns a suggested conversion name.
+         *
+         * <blockquote><table class="sis">
+         *   <caption>Transverse Mercator parameters</caption>
+         *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
+         *   <tr><td>Latitude of natural origin</td>     <td>Given latitude, or 0° if zoned projection</td></tr>
+         *   <tr><td>Longitude of natural origin</td>    <td>Given longitude, optionally snapped to a zone central meridian</td></tr>
+         *   <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr>
+         *   <tr><td>False easting</td>                  <td>500000 metres</td></tr>
+         *   <tr><td>False northing</td>                 <td>0 (North hemisphere) or 10000000 (South hemisphere) metres</td></tr>
+         * </table></blockquote>
+         *
+         * @param  group      the parameters for which to set the values.
+         * @param  zoned      {@code true} for snapping the given latitude/longitude to a zone.
+         * @param  latitude   the latitude in the center of the desired projection.
+         * @param  longitude  the longitude in the center of the desired projection.
+         * @return a name like <cite>"Transverse Mercator"</cite> or <cite>"UTM zone 10N"</cite>,
+         *         depending on the arguments given to this method.
+         */
+        public String setParameters(final ParameterValueGroup group,
+                final boolean zoned, double latitude, double longitude)
+        {
+            final boolean isSouth = MathFunctions.isNegative(latitude);
+            int zone = zone(longitude);
+            if (zoned) {
+                latitude = 0;
+                longitude = centralMeridian(zone);
+            } else if (longitude != centralMeridian(zone)) {
+                zone = 0;
+            }
+            String name = NAME;
+            if (zone != 0) {
+                name = name() + " zone " + zone + (isSouth ? 'S' : 'N');
+            }
+            group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(latitude,  Units.DEGREE);
+            group.parameter(Constants.CENTRAL_MERIDIAN)  .setValue(longitude, Units.DEGREE);
+            group.parameter(Constants.SCALE_FACTOR)      .setValue(scale,     Units.UNITY);
+            group.parameter(Constants.FALSE_EASTING)     .setValue(easting,   Units.METRE);
+            group.parameter(Constants.FALSE_NORTHING)    .setValue(isSouth ? northing : 0, Units.METRE);
+            return name;
         }
-        group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(latitude,  Units.DEGREE);
-        group.parameter(Constants.CENTRAL_MERIDIAN)  .setValue(longitude, Units.DEGREE);
-        group.parameter(Constants.SCALE_FACTOR)      .setValue(0.9996, Units.UNITY);
-        group.parameter(Constants.FALSE_EASTING)     .setValue(500000, Units.METRE);
-        group.parameter(Constants.FALSE_NORTHING)    .setValue(isSouth ? 10000000 : 0, Units.METRE);
-        return name;
-    }
 
-    /**
-     * Computes the UTM zone from a meridian in the zone.
-     *
-     * @param  longitude  a meridian inside the desired zone, in degrees relative to Greenwich.
-     *                    Positive longitudes are toward east, and negative longitudes toward west.
-     * @return the UTM zone number numbered from 1 to 60 inclusive, or 0 if the given central meridian was NaN.
-     *
-     * @since 0.7
-     */
-    public static int zone(double longitude) {
-        /*
-         * Casts to int are equivalent to Math.floor(double) for positive values, which is guaranteed
-         * to be the case here since we normalize the central meridian to the [MIN_VALUE … MAX_VALUE] range.
-         */
-        double z = (longitude - Longitude.MIN_VALUE) / ZONE_WIDTH;                          // Zone number with fractional part.
-        z -= Math.floor(z / ((Longitude.MAX_VALUE - Longitude.MIN_VALUE) / ZONE_WIDTH))     // Roll in the [0 … 60) range.
-                          * ((Longitude.MAX_VALUE - Longitude.MIN_VALUE) / ZONE_WIDTH);
-        return (int) (z + 1);   // Cast only after addition in order to handle NaN as documented.
-    }
+        /**
+         * If the given parameter values are those of an UTM projection, returns the zone number (negative if South).
+         * Otherwise returns 0. It is caller's responsibility to verify that the operation method is {@value #NAME}.
+         *
+         * @param  group  the Transverse Mercator projection parameters.
+         * @return UTM zone number (positive if North, negative if South),
+         *         or 0 if the given parameters are not for a UTM projection.
+         */
+        public int zone(final ParameterValueGroup group) {
+            if (Numerics.epsilonEqual(group.parameter(Constants.SCALE_FACTOR)      .doubleValue(Units.UNITY), scale,   Numerics.COMPARISON_THRESHOLD) &&
+                Numerics.epsilonEqual(group.parameter(Constants.FALSE_EASTING)     .doubleValue(Units.METRE), easting, Formulas.LINEAR_TOLERANCE) &&
+                Numerics.epsilonEqual(group.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(Units.DEGREE),      0, Formulas.ANGULAR_TOLERANCE))
+            {
+                double v = group.parameter(Constants.FALSE_NORTHING).doubleValue(Units.METRE);
+                final boolean isNorth = Numerics.epsilonEqual(v, 0, Formulas.LINEAR_TOLERANCE);
+                if (isNorth || Numerics.epsilonEqual(v, northing, Formulas.LINEAR_TOLERANCE)) {
+                    v = group.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(Units.DEGREE);
+                    int zone = zone(v);
+                    if (Numerics.epsilonEqual(centralMeridian(zone), v, Formulas.ANGULAR_TOLERANCE)) {
+                        if (!isNorth) zone = -zone;
+                        return zone;
+                    }
+                }
+            }
+            return 0;
+        }
 
-    /**
-     * Computes the central meridian of a given UTM zone.
-     *
-     * @param  zone  the UTM zone as a number in the [1 … 60] range.
-     * @return the central meridian of the given UTM zone.
-     *
-     * @since 0.7
-     */
-    public static double centralMeridian(final int zone) {
-        return (zone - 0.5) * ZONE_WIDTH + Longitude.MIN_VALUE;
+        /**
+         * Computes the UTM zone from a meridian in the zone.
+         *
+         * @param  longitude  a meridian inside the desired zone, in degrees relative to Greenwich.
+         *                    Positive longitudes are toward east, and negative longitudes toward west.
+         * @return the UTM zone number numbered from 1 to 60 inclusive, or 0 if the given central meridian was NaN.
+         */
+        public int zone(double longitude) {
+            /*
+             * Casts to int are equivalent to Math.floor(double) for positive values, which is guaranteed
+             * to be the case here since we normalize the central meridian to the [MIN_VALUE … MAX_VALUE] range.
+             */
+            double z = (longitude - origin) / width;                                      // Zone number with fractional part.
+            z -= Math.floor(z / ((Longitude.MAX_VALUE - Longitude.MIN_VALUE) / width))    // Roll in the [0 … 60) range.
+                              * ((Longitude.MAX_VALUE - Longitude.MIN_VALUE) / width);
+            return (int) (z + 1);   // Cast only after addition in order to handle NaN as documented.
+        }
+
+        /**
+         * Computes the central meridian of a given UTM zone.
+         *
+         * @param  zone  the UTM zone as a number in the [1 … 60] range.
+         * @return the central meridian of the given UTM zone.
+         */
+        public double centralMeridian(final int zone) {
+            return (zone - 0.5) * width + origin;
+        }
     }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -1013,7 +1013,7 @@ public class ParameterFormat extends Tab
     @Override
     public Object parse(final CharSequence text, final ParsePosition pos) throws ParseException {
         throw new ParseException(Errors.getResources(displayLocale)
-                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), 0);
+                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), pos.getIndex());
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing;
 
 import java.util.Map;
+import java.util.Objects;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -34,9 +35,6 @@ import org.apache.sis.internal.metadata.
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.collection.Containers.property;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * Description of a spatial and temporal reference system used by a dataset.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -930,7 +930,7 @@ public enum CommonCRS {
         ArgumentChecks.ensureBetween("latitude",   Latitude.MIN_VALUE,     Latitude.MAX_VALUE,     latitude);
         ArgumentChecks.ensureBetween("longitude", -Formulas.LONGITUDE_MAX, Formulas.LONGITUDE_MAX, longitude);
         final boolean isSouth = MathFunctions.isNegative(latitude);
-        final int zone = TransverseMercator.zone(longitude);
+        final int zone = TransverseMercator.Zoner.UTM.zone(longitude);
         final Integer key = isSouth ? -zone : zone;
         ProjectedCRS crs;
         synchronized (cachedUTM) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -252,7 +252,7 @@ final class EPSGFactoryFallback extends
                     } else {
                         continue;
                     }
-                    return crs.UTM(latitude, TransverseMercator.centralMeridian(zone));
+                    return crs.UTM(latitude, TransverseMercator.Zoner.UTM.centralMeridian(zone));
                 }
             }
             if ((kind & (DATUM | CRS)) != 0) {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -148,7 +148,7 @@ final class StandardDefinitions {
             throw new IllegalStateException(e);     // Should not happen with SIS implementation.
         }
         final ParameterValueGroup parameters = method.getParameters().createValue();
-        String name = TransverseMercator.setParameters(parameters, true, latitude, longitude);
+        String name = TransverseMercator.Zoner.UTM.setParameters(parameters, true, latitude, longitude);
         final DefaultConversion conversion = new DefaultConversion(properties(0, name, null, false), method, null, parameters);
 
         name = baseCRS.getName().getCode() + " / " + name;

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -60,8 +60,7 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.iso.SimpleInternationalString;
 
-import static org.apache.sis.internal.referencing.provider.TransverseMercator.zone;
-import static org.apache.sis.internal.referencing.provider.TransverseMercator.centralMeridian;
+import static org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner.UTM;
 
 
 /**
@@ -588,10 +587,10 @@ public class CommonAuthorityFactory exte
              * 42005: WGS 84 / Auto Mollweide         —   defined by "Central_Meridian" only.
              */
             case 42001: isUTM  = true; break;
-            case 42002: isUTM  = (latitude == 0) && (centralMeridian(zone(longitude)) == longitude); break;
-            case 42003: method = "Orthographic";       param = Constants.LATITUDE_OF_ORIGIN;         break;
-            case 42004: method = "Equirectangular";    param = Constants.STANDARD_PARALLEL_1;        break;
-            case 42005: method = "Mollweide";                                                        break;
+            case 42002: isUTM  = (latitude == 0) && (UTM.centralMeridian(UTM.zone(longitude)) == longitude); break;
+            case 42003: method = "Orthographic";       param = Constants.LATITUDE_OF_ORIGIN;  break;
+            case 42004: method = "Equirectangular";    param = Constants.STANDARD_PARALLEL_1; break;
+            case 42005: method = "Mollweide";                                                 break;
             default: throw noSuchAuthorityCode(String.valueOf(projection), code, null);
         }
         /*

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -720,8 +720,7 @@ public abstract class NormalizedProjecti
         /**
          * Default constructor.
          */
-        public Inverse() {
-            NormalizedProjection.this.super();
+        Inverse() {
         }
 
         /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -107,7 +107,6 @@ public class TransverseMercator extends
      * Work around for RFE #4093999 in Sun's bug database
      * ("Relax constraint on placement of this()/super() call in constructors").
      */
-    @SuppressWarnings("fallthrough")
     @Workaround(library="JDK", version="1.7")
     private static Initializer initializer(final OperationMethod method, final Parameters parameters) {
         final boolean isSouth = identMatch(method, "(?i).*\\bSouth\\b.*", TransverseMercatorSouth.IDENTIFIER);
@@ -126,11 +125,10 @@ public class TransverseMercator extends
     }
 
     /**
-     * Work around for RFE #4093999 in Sun's bug database
-     * ("Relax constraint on placement of this()/super() call in constructors").
+     * Creates a new Transverse Mercator projection from the given initializer.
+     * This constructor is used also by {@link ZonedGridSystem}.
      */
-    @Workaround(library="JDK", version="1.7")
-    private TransverseMercator(final Initializer initializer) {
+    TransverseMercator(final Initializer initializer) {
         super(initializer);
         final double φ0 = toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));
         /*
@@ -185,7 +183,7 @@ public class TransverseMercator extends
          *
          * Denormalization
          *   - Scale x and y by B.
-         *   - Subtract M0 to the northing.
+         *   - Subtract M₀ to the northing.
          *   - Multiply by the scale factor (done by the super-class constructor).
          *   - Add false easting and false northing (done by the super-class constructor).
          */

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -176,7 +176,6 @@ public abstract class AbstractMathTransf
          * Constructs an inverse math transform.
          */
         protected Inverse() {
-            AbstractMathTransform1D.this.super();
         }
 
         /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -339,7 +339,6 @@ public abstract class AbstractMathTransf
          * Constructs an inverse math transform.
          */
         protected Inverse() {
-            AbstractMathTransform2D.this.super();
         }
 
         /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -127,7 +127,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.7
+ * @version 0.8
  * @module
  *
  * @see org.apache.sis.referencing.operation.projection.NormalizedProjection
@@ -501,24 +501,33 @@ public class ContextualParameters extend
      *
      * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#createMapProjection(MathTransformFactory)
      */
-    public synchronized MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
+    public MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
             throws FactoryException
     {
-        if (!isFrozen) {
-            freeze();
+        final MathTransform n, d;
+        synchronized (this) {
+            if (!isFrozen) {
+                freeze();
+            }
+            /*
+             * Creates the ConcatenatedTransform, letting the factory returns the cached instance
+             * if the caller already invoked this method previously (which usually do not happen).
+             */
+            n = factory.createAffineTransform(normalize);
+            d = factory.createAffineTransform(denormalize);
+            Matrix m;
+            if ((m = MathTransforms.getMatrix(n)) != null)   normalize = m;
+            if ((m = MathTransforms.getMatrix(d)) != null) denormalize = m;
         }
-        /*
-         * Creates the ConcatenatedTransform, letting the factory returns the cached instance
-         * if the caller already invoked this method previously (which usually do not happen).
-         */
-        final MathTransform n = factory.createAffineTransform(normalize);
-        final MathTransform d = factory.createAffineTransform(denormalize);
-        Matrix m;
-        if ((m = MathTransforms.getMatrix(n)) != null)   normalize = m;
-        if ((m = MathTransforms.getMatrix(d)) != null) denormalize = m;
         if (kernel == null) {   // Undocumented feature useful for MolodenskyTransform constructor.
             return null;
         }
+        /*
+         * Following call must be outside the synchronized block for avoiding dead-lock. This is because the
+         * factory typically contains a WeakHashSet, which invoke in turn the 'equals' methods in this class
+         * (indirectly, through 'kernel' comparison). We need to be outside the synchronized block for having
+         * the locks taken in same order (WeakHashSet lock before the ContextualParameters lock).
+         */
         return factory.createConcatenatedTransform(factory.createConcatenatedTransform(n, kernel), d);
     }
 

Modified: sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Fri Feb 10 07:21:40 2017
@@ -43,6 +43,7 @@ org.apache.sis.internal.referencing.prov
 org.apache.sis.internal.referencing.provider.PolarStereographicNorth
 org.apache.sis.internal.referencing.provider.PolarStereographicSouth
 org.apache.sis.internal.referencing.provider.ObliqueStereographic
+org.apache.sis.internal.referencing.provider.ZonedTransverseMercator
 org.apache.sis.internal.referencing.provider.NTv2
 org.apache.sis.internal.referencing.provider.NADCON
 org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -95,6 +95,7 @@ public final strictfp class ProvidersTes
             PolarStereographicNorth.class,
             PolarStereographicSouth.class,
             ObliqueStereographic.class,
+            ZonedTransverseMercator.class,
             NTv2.class,
             NADCON.class,
             FranceGeocentricInterpolation.class,

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -26,56 +26,60 @@ import static org.junit.Assert.*;
 
 
 /**
- * Tests {@link TransverseMercator} static methods.
+ * Tests {@link TransverseMercator} {@code Zoner} enumeration.
  * This class is about projection parameters only. For test about the Transverse Mercator calculation,
  * see {@link org.apache.sis.referencing.operation.projection.TransverseMercatorTest} instead.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final strictfp class TransverseMercatorTest extends TestCase {
     /**
-     * Tests {@link TransverseMercator#zone(double)}.
+     * Tests {@link TransverseMercator.Zoner#zone(double)}.
      */
     @Test
     public void testZone() {
-        assertEquals(1,  TransverseMercator.zone(-180));
-        assertEquals(10, TransverseMercator.zone(-123));
-        assertEquals(60, TransverseMercator.zone(179.9));
+        assertEquals(1,  TransverseMercator.Zoner.UTM.zone(-180));
+        assertEquals(10, TransverseMercator.Zoner.UTM.zone(-123));
+        assertEquals(60, TransverseMercator.Zoner.UTM.zone(179.9));
     }
 
     /**
-     * Tests {@link TransverseMercator#centralMeridian(int)}.
+     * Tests {@link TransverseMercator.Zoner#centralMeridian(int)}.
      */
     @Test
     public void testCentralMeridian() {
-        assertEquals(-177, TransverseMercator.centralMeridian( 1), STRICT);
-        assertEquals(-123, TransverseMercator.centralMeridian(10), STRICT);
-        assertEquals( 177, TransverseMercator.centralMeridian(60), STRICT);
+        assertEquals(-177, TransverseMercator.Zoner.UTM.centralMeridian( 1), STRICT);
+        assertEquals(-123, TransverseMercator.Zoner.UTM.centralMeridian(10), STRICT);
+        assertEquals( 177, TransverseMercator.Zoner.UTM.centralMeridian(60), STRICT);
     }
 
     /**
-     * Tests {@link TransverseMercator#setParameters(ParameterValueGroup, double, boolean, boolean)}.
+     * Tests {@link TransverseMercator.Zoner#setParameters(ParameterValueGroup, boolean, double, double)}
+     * followed by {@link TransverseMercator.Zoner#zone(ParameterValueGroup)}.
      */
     @Test
     @DependsOnMethod({
         "testZone",
         "testCentralMeridian"
     })
-    public void testCreate() {
+    public void testSetParameters() {
         final ParameterValueGroup p = TransverseMercator.PARAMETERS.createValue();
-        assertEquals("UTM zone 10N", TransverseMercator.setParameters(p, true, 0, -122));
+        assertEquals("UTM zone 10N", TransverseMercator.Zoner.UTM.setParameters(p, true, 0, -122));
         assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
         assertEquals(Constants.FALSE_NORTHING, 0, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT);
+        assertEquals("UTM.zone(parameters)", 10, TransverseMercator.Zoner.UTM.zone(p));
 
-        assertEquals("Transverse Mercator", TransverseMercator.setParameters(p, false, 0, -122));
+        assertEquals("Transverse Mercator", TransverseMercator.Zoner.UTM.setParameters(p, false, 0, -122));
         assertEquals(Constants.CENTRAL_MERIDIAN, -122, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
         assertEquals(Constants.FALSE_NORTHING, 0, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT);
+        assertEquals("UTM.zone(parameters)", 0, TransverseMercator.Zoner.UTM.zone(p));
 
-        assertEquals("UTM zone 10S", TransverseMercator.setParameters(p, false, -0.0, -123));
+        assertEquals("UTM zone 10S", TransverseMercator.Zoner.UTM.setParameters(p, false, -0.0, -123));
         assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
         assertEquals(Constants.FALSE_NORTHING, 10000000, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT);
+        assertEquals("UTM.zone(parameters)", -10, TransverseMercator.Zoner.UTM.zone(p));
     }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -162,6 +162,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.projection.MercatorTest.class,
     org.apache.sis.referencing.operation.projection.LambertConicConformalTest.class,
     org.apache.sis.referencing.operation.projection.TransverseMercatorTest.class,
+    org.apache.sis.referencing.operation.projection.ZonedGridSystemTest.class,
     org.apache.sis.referencing.operation.projection.PolarStereographicTest.class,
     org.apache.sis.referencing.operation.projection.ObliqueStereographicTest.class,
     org.apache.sis.referencing.operation.projection.CylindricalEqualAreaTest.class,

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -209,25 +209,28 @@ public abstract class CompoundFormat<T>
      *   <li>The {@code pos} index is left unchanged</li>
      *   <li>The {@code pos} {@linkplain ParsePosition#getErrorIndex() error index}
      *       is set to the beginning of the unparsable character sequence.</li>
-     *   <li>A {@code ParseException} is thrown with an
-     *       {@linkplain ParseException#getErrorOffset() error offset} relative to the above-cited
-     *       {@code pos} error index. Consequently the exact error location is <var>{@code pos}
-     *       error index</var> + <var>{@code ParseException} error offset</var>.</li>
+     *   <li>One of the following actions is taken (at implementation choice):
+     *     <ul>
+     *       <li>this method returns {@code null}, or</li>
+     *       <li>a {@code ParseException} is thrown with an {@linkplain ParseException#getErrorOffset() error offset}
+     *           set to the index of the first unparsable character. This is usually the same information than the
+     *           above-cited {@code pos} error index, but implementations are free to adopt a slightly different policy.</li>
+     *     </ul>
+     *   </li>
      * </ul>
      *
      * <div class="note"><b>Example:</b>
      * if parsing of the {@code "30.0 40,0"} coordinate fails on the coma in the last number, then the {@code pos}
-     * error index will be set to 5 (the beginning of the {@code "40.0"} character sequence) while the
-     * {@link ParseException} error offset will be set to 2 (the coma position relative the beginning
-     * of the {@code "40.0"} character sequence).</div>
-     *
-     * This error offset policy is a consequence of the compound nature of {@code CompoundFormat},
-     * since the exception may have been produced by a call to {@link Format#parseObject(String)}
-     * on one of the {@linkplain #getFormat(Class) sub-formats} used by this {@code CompoundFormat}.
+     * {@linkplain ParsePosition#getErrorIndex() error index} may be set to 5 (the beginning of the {@code "40.0"}
+     * character sequence) or to 7 (the coma position), depending on the implementation.</div>
+     *
+     * Most implementations never return {@code null}. However some implementations may choose to return {@code null}
+     * if they can determine that the given text is not a supported format and reserve {@code ParseException} for the
+     * cases where the text seems to be the expected format but contains a malformed element.
      *
      * @param  text  the character sequence for the object to parse.
      * @param  pos   the position where to start the parsing.
-     * @return the parsed object.
+     * @return the parsed object, or {@code null} if the text is not recognized.
      * @throws ParseException if an error occurred while parsing the object.
      */
     public abstract T parse(CharSequence text, ParsePosition pos) throws ParseException;
@@ -253,8 +256,6 @@ public abstract class CompoundFormat<T>
      * </ul>
      *
      * The default implementation delegates to {@link #parse(CharSequence, ParsePosition)}.
-     * In case of failure, the {@linkplain ParseException exception error offset} is added
-     * to the {@code pos} error index.
      *
      * @param  text  the string representation of the object to parse.
      * @param  pos   the position where to start the parsing.
@@ -265,7 +266,9 @@ public abstract class CompoundFormat<T>
         try {
             return parse(text, pos);
         } catch (ParseException e) {
-            pos.setErrorIndex(Math.max(pos.getIndex(), pos.getErrorIndex()) + e.getErrorOffset());
+            if (pos.getErrorIndex() < 0) {
+                pos.setErrorIndex(e.getErrorOffset());
+            }
             return null;
         }
     }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -31,6 +31,7 @@ import org.opengis.util.InternationalStr
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.TabularFormat;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.collection.BackingStoreException;
 
@@ -48,7 +49,7 @@ import static java.lang.Math.*;
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  */
 public class StatisticsFormat extends TabularFormat<Statistics> {
@@ -209,14 +210,15 @@ public class StatisticsFormat extends Ta
     }
 
     /**
-     * Not yet implemented.
+     * Not yet supported.
      *
      * @return currently never return.
-     * @throws ParseException currently never thrown.
+     * @throws ParseException currently always thrown.
      */
     @Override
     public Statistics parse(CharSequence text, ParsePosition pos) throws ParseException {
-        throw new UnsupportedOperationException();
+        throw new ParseException(Errors.getResources(getLocale())
+                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), pos.getIndex());
     }
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Angle.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -23,7 +23,16 @@ import java.util.FormattableFlags;
 import java.text.Format;
 import java.text.ParseException;
 import java.io.Serializable;
+import javax.measure.Unit;
+import javax.measure.IncommensurableException;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.internal.util.Utilities;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Classes;
 
 import static java.lang.Double.doubleToLongBits;
 import static org.apache.sis.math.MathFunctions.isNegative;
@@ -58,7 +67,7 @@ import static org.apache.sis.math.MathFu
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  *
  * @see Latitude
@@ -132,6 +141,47 @@ public class Angle implements Comparable
     }
 
     /**
+     * Returns the angular value of the axis having the given direction.
+     * This helper method is used for subclass constructors expecting a {@link DirectPosition} argument.
+     *
+     * @param  position  the position from which to get an angular value.
+     * @param  positive  axis direction of positive values.
+     * @param  negative  axis direction of negative values.
+     * @return angular value in degrees.
+     * @throws IllegalArgumentException if the given coordinate it not associated to a CRS,
+     *         or if no axis oriented toward the given directions is found, or if that axis
+     *         does not use {@linkplain Units#isAngular angular units}.
+     */
+    static double valueOf(final DirectPosition position, final AxisDirection positive, final AxisDirection negative) {
+        final CoordinateReferenceSystem crs = position.getCoordinateReferenceSystem();
+        if (crs == null) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.UnspecifiedCRS));
+        }
+        final CoordinateSystem cs = crs.getCoordinateSystem();
+        final int dimension = cs.getDimension();
+        IncommensurableException cause = null;
+        for (int i=0; i<dimension; i++) {
+            final CoordinateSystemAxis axis = cs.getAxis(i);
+            final AxisDirection dir = axis.getDirection();
+            final boolean isPositive = dir.equals(positive);
+            if (isPositive || dir.equals(negative)) {
+                double value = position.getOrdinate(i);
+                if (!isPositive) value = -value;
+                final Unit<?> unit = axis.getUnit();
+                if (unit != Units.DEGREE) try {
+                    value = unit.getConverterToAny(Units.DEGREE).convert(value);
+                } catch (IncommensurableException e) {
+                    cause = e;
+                    break;
+                }
+                return value;
+            }
+        }
+        throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalCRSType_1,
+                Classes.getLeafInterfaces(crs.getClass(), CoordinateReferenceSystem.class)[0]), cause);
+    }
+
+    /**
      * Returns the angle value in decimal degrees.
      *
      * @return the angle value in decimal degrees.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Latitude.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -16,6 +16,9 @@
  */
 package org.apache.sis.measure;
 
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.cs.AxisDirection;
+
 
 /**
  * A latitude angle in decimal degrees.
@@ -47,7 +50,7 @@ package org.apache.sis.measure;
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.8
  * @module
  *
  * @see Longitude
@@ -104,6 +107,29 @@ public final class Latitude extends Angl
     }
 
     /**
+     * Constructs a newly allocated object containing the latitude value of the given position.
+     * For this method, the latitude value is defined as the angular value associated to the first axis
+     * oriented toward {@linkplain AxisDirection#NORTH North} or {@linkplain AxisDirection#SOUTH South}.
+     * Note that this is not necessarily the <cite>geodetic latitudes</cite> used in
+     * {@linkplain org.apache.sis.referencing.crs.DefaultGeographicCRS geographic CRS};
+     * it may also be <cite>geocentric latitudes</cite>.
+     *
+     * <p>If the axis direction is South, then the sign of the ordinate value is inverted.
+     * If the ordinate value uses another angular units than {@linkplain Units#DEGREE degrees},
+     * then a unit conversion is applied.</p>
+     *
+     * @param  position  the coordinate from which to extract the latitude value in degrees.
+     * @throws IllegalArgumentException if the given coordinate it not associated to a CRS,
+     *         or if no axis oriented toward North or South is found, or if that axis does
+     *         not use {@linkplain Units#isAngular angular units}.
+     *
+     * @since 0.8
+     */
+    public Latitude(final DirectPosition position) throws IllegalArgumentException {
+        super(valueOf(position, AxisDirection.NORTH, AxisDirection.SOUTH));
+    }
+
+    /**
      * Returns the hemisphere character for an angle of the given sign.
      * This is used only by {@link #toString()}, not by {@link AngleFormat}.
      */

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -16,6 +16,10 @@
  */
 package org.apache.sis.measure;
 
+import static org.apache.sis.measure.Angle.valueOf;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.cs.AxisDirection;
+
 
 /**
  * A longitude angle in decimal degrees.
@@ -32,7 +36,7 @@ package org.apache.sis.measure;
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.8
  * @module
  *
  * @see Latitude
@@ -90,6 +94,29 @@ public final class Longitude extends Ang
     }
 
     /**
+     * Constructs a newly allocated object containing the longitude value of the given position.
+     * For this method, the longitude value is defined as the angular value associated to the first axis
+     * oriented toward {@linkplain AxisDirection#EAST East} or {@linkplain AxisDirection#WEST West}.
+     * Note that this is not necessarily the <cite>geodetic longitudes</cite> used in
+     * {@linkplain org.apache.sis.referencing.crs.DefaultGeographicCRS geographic CRS};
+     * it may also be <cite>geocentric longitudes</cite>.
+     *
+     * <p>If the axis direction is West, then the sign of the ordinate value is inverted.
+     * If the ordinate value uses another angular units than {@linkplain Units#DEGREE degrees},
+     * then a unit conversion is applied.</p>
+     *
+     * @param  position  the coordinate from which to extract the longitude value in degrees.
+     * @throws IllegalArgumentException if the given coordinate it not associated to a CRS,
+     *         or if no axis oriented toward East or West is found, or if that axis does
+     *         not use {@linkplain Units#isAngular angular units}.
+     *
+     * @since 0.8
+     */
+    public Longitude(final DirectPosition position) throws IllegalArgumentException {
+        super(valueOf(position, AxisDirection.EAST, AxisDirection.WEST));
+    }
+
+    /**
      * Returns the hemisphere character for an angle of the given sign.
      * This is used only by {@link #toString()}, not by {@link AngleFormat}.
      */

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -324,7 +324,7 @@ public class TreeTableFormat extends Tab
 
     /**
      * Creates a tree from the given character sequence,
-     * or returns {@code null} if an error occurred while parsing the characters.
+     * or returns {@code null} if the given text does not look like a tree for this method.
      * This method can parse the trees created by the {@code format(…)} methods
      * defined in this class.
      *
@@ -338,12 +338,23 @@ public class TreeTableFormat extends Tab
      *     </ol>
      *   </li>
      *   <li>The number of spaces and drawing characters before the node values determines the node
-     *       indentation. This indentation doesn't need to be a factor of the {@link #getIndentation()}
+     *       indentation. This indentation does not need to be a factor of the {@link #getIndentation()}
      *       value, but must be consistent across all the parsed tree.</li>
      *   <li>The indentation determines the parent of each node.</li>
      *   <li>Parsing stops at first empty line (ignoring whitespaces), or at the end of the given text.</li>
      * </ul>
      *
+     * <div class="section">Error index</div>
+     * If the given text does not seem to be a tree table, then this method returns {@code null}.
+     * Otherwise if parsing started but failed, then:
+     *
+     * <ul>
+     *   <li>{@link ParsePosition#getErrorIndex()} will give the index at the beginning
+     *       of line or beginning of cell where the error occurred, and</li>
+     *   <li>{@link ParseException#getErrorOffset()} will give either the same value,
+     *       or a slightly more accurate value inside the cell.</li>
+     * </ul>
+     *
      * @param  text  the character sequence for the tree to parse.
      * @param  pos   the position where to start the parsing.
      * @return the parsed tree, or {@code null} if the given character sequence can not be parsed.
@@ -403,26 +414,31 @@ public class TreeTableFormat extends Tab
              * text are not parsed (the value is left to null).
              */
             final TreeTable.Node node = new DefaultTreeTable.Node(table);
-            try {
-                matcher.region(indexOfValue, endOfLine);
-                for (int ci=0; ci<columns.length; ci++) {
-                    final boolean found = matcher.find();
-                    int endOfColumn = found ? matcher.start() : endOfLine;
-                    indexOfValue   = CharSequences.skipLeadingWhitespaces (text, indexOfValue, endOfColumn);
-                    int endOfValue = CharSequences.skipTrailingWhitespaces(text, indexOfValue, endOfColumn);
-                    if (endOfValue > indexOfValue) {
-                        parseValue(node, columns[ci], formats[ci], text.subSequence(indexOfValue, endOfValue).toString());
+            matcher.region(indexOfValue, endOfLine);
+            for (int ci=0; ci<columns.length; ci++) {
+                final boolean found = matcher.find();
+                int endOfColumn = found ? matcher.start() : endOfLine;
+                indexOfValue   = CharSequences.skipLeadingWhitespaces (text, indexOfValue, endOfColumn);
+                int endOfValue = CharSequences.skipTrailingWhitespaces(text, indexOfValue, endOfColumn);
+                if (endOfValue > indexOfValue) {
+                    final String valueText = text.subSequence(indexOfValue, endOfValue).toString();
+                    try {
+                        parseValue(node, columns[ci], formats[ci], valueText);
+                    } catch (ParseException | ClassCastException e) {
+                        pos.setErrorIndex(indexOfValue);                                    // See method javadoc.
+                        if (e instanceof ParseException) {
+                            indexOfValue += ((ParseException) e).getErrorOffset();
+                        }
+                        throw new LocalizedParseException(getDisplayLocale(), Errors.Keys.UnparsableStringForClass_2,
+                                new Object[] {columns[ci].getElementType(), valueText}, indexOfValue).initCause(e);
                     }
-                    if (!found) break;
-                    /*
-                     * The end of this column will be the beginning of the next column,
-                     * after skipping the last character of the column separator.
-                     */
-                    indexOfValue = matcher.end();
                 }
-            } catch (ParseException e) {
-                pos.setErrorIndex(indexOfValue);
-                throw e;
+                if (!found) break;
+                /*
+                 * The end of this column will be the beginning of the next column,
+                 * after skipping the last character of the column separator.
+                 */
+                indexOfValue = matcher.end();
             }
             /*
              * If this is the first node created so far, it will be the root.
@@ -441,7 +457,7 @@ public class TreeTableFormat extends Tab
                     if (--indentationLevel < 0) {
                         pos.setErrorIndex(indexOfLineStart);
                         throw new LocalizedParseException(getDisplayLocale(),
-                                Errors.Keys.NodeHasNoParent_1, new Object[] {node}, 0);
+                                Errors.Keys.NodeHasNoParent_1, new Object[] {node}, indexOfLineStart);
                     }
                     lastNode = lastNode.getParent();
                 }
@@ -455,7 +471,7 @@ public class TreeTableFormat extends Tab
                     if (parent == null) {
                         pos.setErrorIndex(indexOfLineStart);
                         throw new LocalizedParseException(getDisplayLocale(),
-                                Errors.Keys.NodeHasNoParent_1, new Object[] {node}, 0);
+                                Errors.Keys.NodeHasNoParent_1, new Object[] {node}, indexOfLineStart);
                     }
                     parent.getChildren().add(node);
                 } else if (i > p) {
@@ -485,12 +501,16 @@ public class TreeTableFormat extends Tab
      * Parses the given string using a format appropriate for the type of values in
      * the given column, and stores the value in the given node.
      *
+     * <p>This work is done in a separated method instead than inlined in the
+     * {@code parse(…)} method because of the {@code <V>} parametric value.</p>
+     *
      * @param  V        the type of values in the given column.
      * @param  node     the node in which to set the value.
      * @param  column   the column in which to set the value.
      * @param  format   the format to use for parsing the value, or {@code null}.
      * @param  text     the textual representation of the value.
      * @throws ParseException if an error occurred while parsing.
+     * @throws ClassCastException if the parsed value is not of the expected type.
      */
     private <V> void parseValue(final TreeTable.Node node, final TableColumn<V> column,
             final Format format, final String text) throws ParseException

Modified: sis/trunk/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java?rev=1782436&r1=1782435&r2=1782436&view=diff
==============================================================================
--- sis/trunk/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] (original)
+++ sis/trunk/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] Fri Feb 10 07:21:40 2017
@@ -904,7 +904,7 @@ final class LandsatReader {
          */
         if (datum != null) {
             if (utmZone > 0) {
-                metadata.add(datum.UTM(1, TransverseMercator.centralMeridian(utmZone)));
+                metadata.add(datum.UTM(1, TransverseMercator.Zoner.UTM.centralMeridian(utmZone)));
             }
             if (projection != null) {
                 final double sp = projection.parameter(Constants.STANDARD_PARALLEL_1).doubleValue();

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=1782436&r1=1782435&r2=1782436&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] Fri Feb 10 07:21:40 2017
@@ -28,6 +28,7 @@ import org.opengis.metadata.citation.Onl
 import org.opengis.metadata.content.ContentInformation;
 import org.apache.sis.storage.gps.Fix;
 import org.apache.sis.storage.FeatureNaming;
+import org.apache.sis.storage.IllegalNameException;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.feature.AbstractIdentifiedType;
 import org.apache.sis.feature.FeatureOperations;
@@ -41,7 +42,6 @@ import org.apache.sis.util.Static;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.Temporal;
-import org.apache.sis.storage.IllegalNameException;
 import org.apache.sis.feature.DefaultFeatureType;
 
 



Mime
View raw message