sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1724259 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ sis-referencing/src/main/java/org/apache/sis/referencing/ ...
Date Tue, 12 Jan 2016 15:28:13 GMT
Author: desruisseaux
Date: Tue Jan 12 15:28:13 2016
New Revision: 1724259

URL: http://svn.apache.org/viewvc?rev=1724259&view=rev
Log:
Cleanup and add test for CommonCRS.UTM(latitude, longitude).
This method will be needed for AUTO:42001 and AUTO:42002 codes.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java   (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -18,6 +18,7 @@ package org.apache.sis.internal.referenc
 
 import org.apache.sis.util.Static;
 import org.apache.sis.measure.Latitude;
+import org.apache.sis.internal.util.Numerics;
 
 import static java.lang.Math.*;
 import static org.apache.sis.math.MathFunctions.atanh;
@@ -31,7 +32,7 @@ import static org.apache.sis.internal.me
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public final class Formulas extends Static {
@@ -58,6 +59,14 @@ public final class Formulas extends Stat
     public static final double ANGULAR_TOLERANCE = LINEAR_TOLERANCE / (NAUTICAL_MILE * 60);
 
     /**
+     * The maximal longitude value before normalization if a centimetric precision is desired.
+     * This is about 4×10⁸ degrees.
+     *
+     * @see org.apache.sis.measure.Longitude#normalize(double)
+     */
+    public static final double LONGITUDE_MAX = (1L << Numerics.SIGNIFICAND_SIZE) * ANGULAR_TOLERANCE;
+
+    /**
      * The length of a <cite>Julian year</cite> in milliseconds.
      * From Wikipedia, <cite>"In astronomy, a Julian year (symbol: <b>a</b>) is a unit of measurement of time
      * defined as exactly 365.25 days of 86,400 SI seconds each."</cite>.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -168,7 +168,7 @@ public final class Equirectangular exten
         LATITUDE_OF_ORIGIN = createZeroConstant(builder     // Was used by EPSG:9823 (also EPSG:9842).
                 .addIdentifier("8801")
                 .addName("Latitude of natural origin")
-                .addName(Citations.OGC,     "latitude_of_origin")
+                .addName(Citations.OGC,     Constants.LATITUDE_OF_ORIGIN)
                 .addName(Citations.ESRI,    "Latitude_Of_Origin")
                 .addName(Citations.NETCDF,  "latitude_of_projection_origin")
                 .addName(Citations.GEOTIFF, "ProjCenterLat")

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -58,6 +58,11 @@ public final class TransverseMercator ex
     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";
+
+    /**
      * The operation parameter descriptor for the <cite>Latitude of natural origin</cite> (φ₀) parameter value.
      * Valid values range is [-90 … 90]° and default value is 0°.
      */
@@ -78,7 +83,7 @@ public final class TransverseMercator ex
     /**
      * The group of all parameters expected by this coordinate operation.
      */
-    private static final ParameterDescriptorGroup PARAMETERS;
+    static final ParameterDescriptorGroup PARAMETERS;
     static {
         final ParameterBuilder builder = builder();
         LATITUDE_OF_ORIGIN = createLatitude(builder
@@ -94,7 +99,7 @@ public final class TransverseMercator ex
 
         PARAMETERS = builder
                 .addIdentifier(              "9807")
-                .addName(                    "Transverse Mercator")
+                .addName(                    NAME)
                 .addName(                    "Gauss-Kruger")
                 .addName(                    "Gauss-Boaga")
                 .addName(                    "TM")
@@ -141,57 +146,57 @@ public final class TransverseMercator ex
      *   <caption>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>Central meridian, optionally snapped to a UTM zone</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  centralMeridian  The longitude in the center of the desired projection.
-     * @param  isUTM            If {@code true}, the given central meridian will be snapped to the central meridian of a UTM zone.
-     * @param  isSouth          {@code false} for a projection in the North hemisphere, or {@code true} for the South hemisphere.
+     * @param  group      The parameters for which to set the values.
+     * @param  longitude  The longitude in the center of the desired projection.
+     * @param  isUTM      If {@code true}, the given longitude will be snapped to the central meridian of a UTM zone.
+     * @param  isSouth    {@code false} for a projection in the North hemisphere, or {@code true} for the South hemisphere.
      * @return A name like <cite>"Transverse Mercator"</cite> or <cite>"UTM zone 10N"</cite>,
      *         depending on the arguments given to this method.
      *
      * @since 0.7
      */
     public static String setParameters(final ParameterValueGroup group,
-            double centralMeridian, final boolean isUTM, final boolean isSouth)
+            double longitude, final boolean isUTM, final boolean isSouth)
     {
-        int zone = zone(centralMeridian);
+        int zone = zone(longitude);
         if (isUTM) {
-            centralMeridian = centralMeridian(zone);
-        } else if (centralMeridian != centralMeridian(zone)) {
+            longitude = centralMeridian(zone);
+        } else if (longitude != centralMeridian(zone)) {
             zone = 0;
         }
-        String name = "Transverse Mercator";
+        String name = NAME;
         if (zone != 0) {
             name = "UTM zone " + zone + (isSouth ? 'S' : 'N');
         }
-        group.parameter("latitude_of_origin")       .setValue(0, NonSI.DEGREE_ANGLE);
-        group.parameter(Constants.CENTRAL_MERIDIAN) .setValue(centralMeridian, NonSI.DEGREE_ANGLE);
-        group.parameter(Constants.SCALE_FACTOR)     .setValue(0.9996, Unit.ONE);
-        group.parameter(Constants.FALSE_EASTING)    .setValue(500000, SI.METRE);
-        group.parameter(Constants.FALSE_NORTHING)   .setValue(isSouth ? 10000000 : 0, SI.METRE);
+        group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(0, NonSI.DEGREE_ANGLE);
+        group.parameter(Constants.CENTRAL_MERIDIAN)  .setValue(longitude, NonSI.DEGREE_ANGLE);
+        group.parameter(Constants.SCALE_FACTOR)      .setValue(0.9996, Unit.ONE);
+        group.parameter(Constants.FALSE_EASTING)     .setValue(500000, SI.METRE);
+        group.parameter(Constants.FALSE_NORTHING)    .setValue(isSouth ? 10000000 : 0, SI.METRE);
         return name;
     }
 
     /**
      * Computes the UTM zone from a meridian in the zone.
      *
-     * @param  centralMeridian A meridian inside the desired zone, in degrees relative to Greenwich.
+     * @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 centralMeridian) {
+    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 = (centralMeridian - Longitude.MIN_VALUE) / ZONE_WIDTH;                    // Zone number with fractional part.
+        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.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -19,6 +19,7 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.Iterator;
 import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
 import javax.measure.unit.Unit;
@@ -59,12 +60,16 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.crs.DefaultGeocentricCRS;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.math.MathFunctions;
+import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Units;
 
 import static java.util.Collections.singletonMap;
@@ -339,7 +344,7 @@ public enum CommonCRS {
      * The Universal Transverse Mercator projections, created when first needed.
      * All accesses to this map shall be synchronized on {@code cachedUTM}.
      *
-     * @see #UTM(double, boolean)
+     * @see #UTM(double, double)
      */
     private final Map<Integer,ProjectedCRS> cachedUTM;
 
@@ -805,18 +810,45 @@ public enum CommonCRS {
     }
 
     /**
-     * Returns a Universal Transverse Mercator projection for the zone containing the given meridian.
-     * If the given central meridian is not between -180° and 180°, then it will be rolled into that range.
-     * If the given central meridian is not in the center of a UTM zone, then it will be snapped to the center.
-     *
-     * @param  centralMeridian  The longitude in the center of the desired projection.
-     * @param  isSouth          {@code false} for a projection in the North hemisphere, or {@code true} for the South hemisphere.
-     * @return A Universal Transverse Mercator projection for the zone containing the given meridian.
+     * Returns a Universal Transverse Mercator (UTM) projection for the zone containing the given point.
+     * There is a total of 120 UTM zones, with 60 zones in the North hemisphere and 60 zones in the South hemisphere.
+     * The projection zone is determined from the arguments as below:
+     *
+     * <ul>
+     *   <li>The sign of the <var>latitude</var> argument determines the hemisphere:
+     *       North for positive latitudes (including positive zero) or
+     *       South for negative latitudes (including negative zero).
+     *       The latitude magnitude is ignored, except for ensuring that the latitude is inside the [-90 … 90]° range.</li>
+     *   <li>The value of the <var>longitude</var> argument determines the 6°-width zone,
+     *       numbered from 1 for the zone starting at 180°W up to 60 for the zone finishing at 180°E.
+     *       Longitudes outside the [-180 … 180]° range will be rolled as needed before to compute the zone.</li>
+     * </ul>
+     *
+     * The map projection uses the following parameters:
+     *
+     * <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>0°</td></tr>
+     *   <tr><td>Longitude of natural origin</td>    <td>Central meridian of the UTM zone containing the given longitude</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>
+     *
+     * The coordinate system axes are (Easting, Northing) in metres.
+     *
+     * @param  latitude  A latitude in the desired UTM projection zone.
+     * @param  longitude A longitude in the desired UTM projection zone.
+     * @return A Universal Transverse Mercator projection for the zone containing the given point.
      *
      * @since 0.7
      */
-    public ProjectedCRS UTM(final double centralMeridian, final boolean isSouth) {
-        final int zone = TransverseMercator.zone(centralMeridian);
+    public ProjectedCRS UTM(final double latitude, final double longitude) {
+        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 Integer key = isSouth ? -zone : zone;
         ProjectedCRS crs;
         synchronized (cachedUTM) {
@@ -841,13 +873,21 @@ public enum CommonCRS {
              * We will arbitrarily create this CS only for a frequently created CRS, and share that
              * CS instance for all other constants.
              */
-            final CartesianCS cs;
-            if (this == DEFAULT && zone == 31 && !isSouth) {    // MUST be the zone of 3°
-                cs = (CartesianCS) StandardDefinitions.createCoordinateSystem((short) 4400);
-            } else {
-                cs = DEFAULT.UTM(3, false).getCoordinateSystem();
+            CartesianCS cs = null;
+            synchronized (DEFAULT.cachedUTM) {
+                final Iterator<ProjectedCRS> it = DEFAULT.cachedUTM.values().iterator();
+                if (it.hasNext()) {
+                    cs = it.next().getCoordinateSystem();
+                }
             }
-            crs = StandardDefinitions.createUTM(code, geographic(), centralMeridian, isSouth, cs);
+            if (cs == null) {
+                if (this != DEFAULT) {
+                    cs = DEFAULT.UTM(latitude, longitude).getCoordinateSystem();
+                } else {
+                    cs = (CartesianCS) StandardDefinitions.createCoordinateSystem((short) 4400);
+                }
+            }
+            crs = StandardDefinitions.createUTM(code, geographic(), longitude, isSouth, cs);
             final ProjectedCRS other;
             synchronized (cachedUTM) {
                 other = cachedUTM.putIfAbsent(key, crs);
@@ -859,6 +899,26 @@ public enum CommonCRS {
         return crs;
     }
 
+    /**
+     * Returns the CRS for the given EPSG code, or {@code null} if none.
+     * This is a helper method for {@link #forCode(String, String, FactoryException)} only.
+     */
+    private CoordinateReferenceSystem forCode(final int code) {
+        if (code == geographic) return geographic();
+        if (code == geocentric) return geocentric();
+        if (code == geo3D)      return geographic3D();
+        final double latitude;
+        int zone;
+        if (northUTM != 0 && (zone = code - northUTM) >= firstZone && zone <= lastZone) {
+            latitude = +1;
+        } else if (southUTM != 0 && (zone = code - southUTM) >= firstZone && zone <= lastZone) {
+            latitude = -1;
+        } else {
+            return null;
+        }
+        return UTM(latitude, TransverseMercator.centralMeridian(zone));
+    }
+
 
 
 
@@ -1494,9 +1554,10 @@ public enum CommonCRS {
                 final int n = Integer.parseInt(code);
                 if (n != 0) { // CommonCRS uses 0 as a sentinel value for "no EPSG code".
                     for (final CommonCRS candidate : CommonCRS.values()) {
-                        if (candidate.geographic == n) return candidate.geographic();
-                        if (candidate.geocentric == n) return candidate.geocentric();
-                        if (candidate.geo3D      == n) return candidate.geographic3D();
+                        final CoordinateReferenceSystem crs = candidate.forCode(n);
+                        if (crs != null) {
+                            return crs;
+                        }
                     }
                     for (final CommonCRS.Vertical candidate : CommonCRS.Vertical.values()) {
                         if (candidate.isEPSG && candidate.crs == n) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -127,23 +127,25 @@ final class StandardDefinitions {
      * This method restricts the factory to SIS implementation instead than arbitrary factory in order to meet
      * the contract saying that {@link CommonCRS} methods should never fail.
      *
-     * @param code             The EPSG code, or 0 if none.
-     * @param baseCRS          The geographic CRS on which the projected CRS is based.
-     * @param centralMeridian  The longitude in the center of the desired projection.
-     * @param isSouth          {@code false} for a projection in the North hemisphere, or {@code true} for the South hemisphere.
-     * @param derivedCS        The projected coordinate system.
+     * @param code       The EPSG code, or 0 if none.
+     * @param baseCRS    The geographic CRS on which the projected CRS is based.
+     * @param longitude  A longitude in the zone of the desired projection, to be snapped to UTM central meridian.
+     * @param isSouth    {@code false} for a projection in the North hemisphere, or {@code true} for the South hemisphere.
+     * @param derivedCS  The projected coordinate system.
      */
     static ProjectedCRS createUTM(final int code, final GeographicCRS baseCRS,
-            final double centralMeridian, final boolean isSouth, final CartesianCS derivedCS)
+            final double longitude, final boolean isSouth, final CartesianCS derivedCS)
     {
         final OperationMethod method;
         try {
-            method = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class).getOperationMethod("Transverse Mercator");
+            method = DefaultFactories.forBuildin(MathTransformFactory.class,
+                                          DefaultMathTransformFactory.class)
+                    .getOperationMethod(TransverseMercator.NAME);
         } catch (NoSuchIdentifierException e) {
             throw new IllegalStateException(e);     // Should not happen with SIS implementation.
         }
         final ParameterValueGroup parameters = method.getParameters().createValue();
-        String name = TransverseMercator.setParameters(parameters, centralMeridian, true, isSouth);
+        String name = TransverseMercator.setParameters(parameters, longitude, true, isSouth);
         final DefaultConversion conversion = new DefaultConversion(properties(0, name, null, false), method, null, parameters);
 
         name = baseCRS.getName().getCode() + " / " + name;
@@ -353,6 +355,16 @@ final class StandardDefinitions {
         RangeMeaning rm = null;
         final AxisDirection dir;
         switch (code) {
+            case 1:    name = "Easting";
+                       abrv = "E";
+                       unit = SI.METRE;
+                       dir  = AxisDirection.EAST;
+                       break;
+            case 2:    name = "Northing";
+                       abrv = "N";
+                       unit = SI.METRE;
+                       dir  = AxisDirection.NORTH;
+                       break;
             case 108:  // Used in Ellipsoidal 3D.
             case 106:  name = AxisNames.GEODETIC_LATITUDE;
                        abrv = "φ";

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -122,7 +122,7 @@ import org.apache.sis.util.iso.SimpleInt
  *     <td>WGS 84 / Auto UTM</td>
  *     <td>{@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected}</td>
  *     <td>{@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian}</td>
- *     <td>up</td>
+ *     <td>(east, north)</td>
  *     <td>user-specified</td>
  *   </tr><tr>
  *     <td>AUTO2</td>
@@ -130,7 +130,7 @@ import org.apache.sis.util.iso.SimpleInt
  *     <td>WGS 84 / Auto Tr Mercator</td>
  *     <td>{@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected}</td>
  *     <td>{@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian}</td>
- *     <td>up</td>
+ *     <td>(east, north)</td>
  *     <td>user-specified</td>
  *   </tr><tr>
  *     <td>AUTO2</td>
@@ -138,7 +138,7 @@ import org.apache.sis.util.iso.SimpleInt
  *     <td>WGS 84 / Auto Orthographic</td>
  *     <td>{@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected}</td>
  *     <td>{@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian}</td>
- *     <td>up</td>
+ *     <td>(east, north)</td>
  *     <td>user-specified</td>
  *   </tr><tr>
  *     <td>AUTO2</td>
@@ -146,7 +146,7 @@ import org.apache.sis.util.iso.SimpleInt
  *     <td>WGS 84 / Auto Equirectangular</td>
  *     <td>{@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected}</td>
  *     <td>{@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian}</td>
- *     <td>up</td>
+ *     <td>(east, north)</td>
  *     <td>user-specified</td>
  *   </tr><tr>
  *     <td>AUTO2</td>
@@ -154,7 +154,7 @@ import org.apache.sis.util.iso.SimpleInt
  *     <td>WGS 84 / Auto Mollweide</td>
  *     <td>{@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected}</td>
  *     <td>{@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian}</td>
- *     <td>up</td>
+ *     <td>(east, north)</td>
  *     <td>user-specified</td>
  *   </tr>
  * </table>
@@ -170,7 +170,7 @@ import org.apache.sis.util.iso.SimpleInt
  * <div class="section">Note on codes in AUTO(2) namespace</div>
  * The format is usually "{@code AUTO2:}<var>n</var>,<var>factor</var>,<var>λ₀</var>,<var>φ₀</var>"
  * where <var>n</var> is a number between 42001 and 42005 inclusive, <var>factor</var> is a conversion
- * factor from the CRS units to metres (e.g. 0.3048 for a CRS in feet) and (<var>λ₀</var>,<var>φ₀</var>)
+ * factor from the CRS units to metres (e.g. 0.3048 for a CRS with axes in feet) and (<var>λ₀</var>,<var>φ₀</var>)
  * is the longitude and latitude of a point in the projection centre.
  *
  * <div class="note"><b>Examples:</b>
@@ -469,8 +469,7 @@ public class CommonAuthorityFactory exte
                                                                  parameters[count - 2],
                                                                  parameters[count - 1]);
             }
-            throw new NoSuchAuthorityCodeException(Errors.format(errorKey, expected, count),
-                    AUTO2, localCode, code);
+            throw new NoSuchAuthorityCodeException(Errors.format(errorKey, expected, count), AUTO2, localCode, code);
         }
         if (count != 0) {
             throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnexpectedCharactersAfter_2,
@@ -493,39 +492,42 @@ public class CommonAuthorityFactory exte
      *
      * @param  code        The user-specified code, used only for error reporting.
      * @param  projection  The projection code (e.g. 42001).
+     * @param  factor      The multiplication factor for the unit of measurement.
+     * @param  longitude   A longitude in the desired projection zone.
+     * @param  latitude    A latitude in the desired projection zone.
      * @return The projected CRS for the given projection and parameters.
      */
     @SuppressWarnings("fallthrough")
     private static ProjectedCRS createAuto(final String code, final int projection,
             final double factor, final double longitude, final double latitude) throws FactoryException
     {
-        if (!Double.isInfinite(longitude) && !Double.isNaN(longitude) && !Double.isNaN(latitude) && factor > 0) {
-            /*
-             * 42001: Universal Transverse Mercator   —   central meridian must be in the center of a UTM zone.
-             * 42002: Transverse Mercator             —   like 42001 except that central meridian can be anywhere.
-             */
-            boolean isUTM = (projection == 42001);
-            if (isUTM || projection == 42002) {
-                final boolean isSouth = MathFunctions.isNegative(latitude);
-                final CartesianCS cs;
-                if (factor == 1) {
-                    if (!isUTM) {
-                        isUTM = TransverseMercator.centralMeridian(TransverseMercator.zone(longitude)) == longitude;
-                    }
-                    if (isUTM) {
-                        return CommonCRS.WGS84.UTM(longitude, isSouth);
+        IllegalArgumentException failure = null;
+        try {
+            boolean isUTM = false;
+            switch (projection) {
+                /*
+                 * 42001: Universal Transverse Mercator   —   central meridian must be in the center of a UTM zone.
+                 * 42002: Transverse Mercator             —   like 42001 except that central meridian can be anywhere.
+                 */
+                case 42001: isUTM = true;   // Fall through
+                case 42002: {
+                    ProjectedCRS crs = CommonCRS.WGS84.UTM(latitude, longitude);
+                    if (factor != 1 || (!isUTM && TransverseMercator.centralMeridian(TransverseMercator.zone(longitude)) != longitude)) {
+                        CartesianCS cs = crs.getCoordinateSystem();       // In metres
+                        if (factor != 1) {
+                            // TODO
+                        }
+                        crs = new GeodeticObjectBuilder()
+                                .setTransverseMercator(longitude, isUTM, MathFunctions.isNegative(latitude))
+                                .createProjectedCRS(crs.getBaseCRS(), cs);
                     }
-                    cs = CommonCRS.WGS84.UTM(3, false).getCoordinateSystem();       // In metres.
-                } else {
-                    cs = null;  // TODO
+                    return crs;
                 }
-                return new GeodeticObjectBuilder().setTransverseMercator(factor, isUTM, isSouth)
-                        .createProjectedCRS(CommonCRS.WGS84.geographic(), cs);
             }
+        } catch (IllegalArgumentException e) {
+            failure = e;
         }
-        final String localCode = String.valueOf(projection);
-        throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.NoSuchAuthorityCode_3,
-            AUTO2, ProjectedCRS.class, localCode), AUTO2, localCode, code);
+        throw noSuchAuthorityCode(true, String.valueOf(projection), code, failure);
     }
 
     /**
@@ -551,17 +553,17 @@ public class CommonAuthorityFactory exte
     /**
      * Creates an exception for an unknown authority code.
      *
-     * @param  code       The unknown authority code, without namespace.
-     * @param  identifier The unknown authority code as specified by the user (may include namespace).
+     * @param  localCode  The unknown authority code, without namespace.
+     * @param  code       The unknown authority code as specified by the user (may include namespace).
      * @param  cause      The failure cause, or {@code null} if none.
      * @return An exception initialized with an error message built from the specified informations.
      */
     private static NoSuchAuthorityCodeException noSuchAuthorityCode(final boolean isAuto,
-            final String code, final String identifier, final Exception cause)
+            final String localCode, final String code, final Exception cause)
     {
         NoSuchAuthorityCodeException e = new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.NoSuchAuthorityCode_3,
-                Constants.OGC, isAuto ? ProjectedCRS.class : CoordinateReferenceSystem.class, code),
-                Constants.OGC, code, identifier);
+                Constants.OGC, isAuto ? ProjectedCRS.class : CoordinateReferenceSystem.class, localCode),
+                Constants.OGC, localCode, code);
         e.initCause(cause);
         return e;
     }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.referencing;
 
 import org.apache.sis.internal.metadata.ReferencingServices;
+import org.apache.sis.measure.Longitude;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -28,15 +29,24 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 public final strictfp class FormulasTest extends TestCase {
     /**
+     * Verifies the {@link Formulas#LONGITUDE_MAX} constant.
+     */
+    @Test
+    public void verifyLongitudeMax() {
+        assertTrue(Formulas.LONGITUDE_MAX > Longitude.MAX_VALUE);
+        assertTrue(StrictMath.ulp(Formulas.LONGITUDE_MAX) <= Formulas.ANGULAR_TOLERANCE);
+    }
+
+    /**
      * Verifies the {@link Formulas#JULIAN_YEAR_LENGTH} constant.
      */
     @Test
-    public void testConstants() {
+    public void verifyJulianYearLength() {
         assertEquals(StrictMath.round(365.25 * 24 * 60 * 60 * 1000), Formulas.JULIAN_YEAR_LENGTH);
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -64,12 +64,12 @@ public final strictfp class MapProjectio
         assertParamEquals(null,                                   SEMI_MAJOR,          true,  it.next());
         assertParamEquals(null,                                   SEMI_MINOR,          true,  it.next());
         assertParamEquals("Latitude of 1st standard parallel",    STANDARD_PARALLEL_1, true,  it.next());
-        assertParamEquals("Latitude of natural origin",          "latitude_of_origin", false, it.next());
+        assertParamEquals("Latitude of natural origin",           LATITUDE_OF_ORIGIN,  false, it.next());
         assertParamEquals("Longitude of natural origin",          CENTRAL_MERIDIAN,    true,  it.next());
         assertParamEquals("False easting",                        FALSE_EASTING,       true,  it.next());
         assertParamEquals("False northing",                       FALSE_NORTHING,      true,  it.next());
         assertFalse(it.hasNext());
-        assertIsForcedToZero((ParameterDescriptor<?>) Equirectangular.PARAMETERS.descriptor("latitude_of_origin"));
+        assertIsForcedToZero((ParameterDescriptor<?>) Equirectangular.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
     }
 
     /**
@@ -82,13 +82,13 @@ public final strictfp class MapProjectio
         assertParamEquals("Mercator (variant A)",          "Mercator_1SP",       true, Mercator1SP.PARAMETERS);
         assertParamEquals(null,                             SEMI_MAJOR,          true, it.next());
         assertParamEquals(null,                             SEMI_MINOR,          true, it.next());
-        assertParamEquals("Latitude of natural origin",    "latitude_of_origin", true, it.next());
+        assertParamEquals("Latitude of natural origin",     LATITUDE_OF_ORIGIN,  true, it.next());
         assertParamEquals("Longitude of natural origin",    CENTRAL_MERIDIAN,    true, it.next());
         assertParamEquals("Scale factor at natural origin", SCALE_FACTOR,        true, it.next());
         assertParamEquals("False easting",                  FALSE_EASTING,       true, it.next());
         assertParamEquals("False northing",                 FALSE_NORTHING,      true, it.next());
         assertFalse(it.hasNext());
-        assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor("latitude_of_origin"));
+        assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
     }
 
     /**
@@ -102,13 +102,13 @@ public final strictfp class MapProjectio
         assertParamEquals(null,                                SEMI_MAJOR,           true,  it.next());
         assertParamEquals(null,                                SEMI_MINOR,           true,  it.next());
         assertParamEquals("Latitude of 1st standard parallel", STANDARD_PARALLEL_1,  true,  it.next());
-        assertParamEquals("Latitude of natural origin",        "latitude_of_origin",  false, it.next());
+        assertParamEquals("Latitude of natural origin",        LATITUDE_OF_ORIGIN,   false, it.next());
         assertParamEquals("Longitude of natural origin",       CENTRAL_MERIDIAN,     true,  it.next());
         assertParamEquals(null,                                SCALE_FACTOR,         false, it.next());
         assertParamEquals("False easting",                     FALSE_EASTING,        true,  it.next());
         assertParamEquals("False northing",                    FALSE_NORTHING,       true,  it.next());
         assertFalse(it.hasNext());
-        assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor("latitude_of_origin"));
+        assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
     }
 
     /**

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java?rev=1724259&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.referencing.provider;
+
+import org.opengis.parameter.ParameterValueGroup;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link TransverseMercator} static methods.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final strictfp class TransverseMercatorTest extends TestCase {
+    /**
+     * Tests {@link TransverseMercator#zone(double)}.
+     */
+    @Test
+    public void testZone() {
+        assertEquals(1,  TransverseMercator.zone(-180));
+        assertEquals(10, TransverseMercator.zone(-123));
+        assertEquals(60, TransverseMercator.zone(179.9));
+    }
+
+    /**
+     * Tests {@link TransverseMercator#centralMeridian(int)}.
+     */
+    @Test
+    public void testCentralMeridian() {
+        assertEquals(-177, TransverseMercator.centralMeridian( 1), STRICT);
+        assertEquals(-123, TransverseMercator.centralMeridian(10), STRICT);
+        assertEquals( 177, TransverseMercator.centralMeridian(60), STRICT);
+    }
+
+    /**
+     * Tests {@link TransverseMercator#setParameters(ParameterValueGroup, double, boolean, boolean)}.
+     */
+    @Test
+    @DependsOnMethod({
+        "testZone",
+        "testCentralMeridian"
+    })
+    public void testCreate() {
+        final ParameterValueGroup p = TransverseMercator.PARAMETERS.createValue();
+        assertEquals("UTM zone 10N", TransverseMercator.setParameters(p, -122, true, false));
+        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("Transverse Mercator", TransverseMercator.setParameters(p, -122, false, false));
+        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 10S", TransverseMercator.setParameters(p, -123, false, true));
+        assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
+        assertEquals(Constants.FALSE_NORTHING, 10000000, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -17,13 +17,14 @@
 package org.apache.sis.referencing;
 
 import java.util.Date;
-import org.opengis.test.Validators;
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.GeocentricCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.EllipsoidalCS;
@@ -33,6 +34,9 @@ import org.opengis.referencing.datum.Ver
 import org.apache.sis.internal.metadata.AxisNames;
 import org.apache.sis.internal.metadata.VerticalDatumTypes;
 import org.apache.sis.internal.util.Constants;
+
+// Test dependencies
+import org.opengis.test.Validators;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -47,7 +51,7 @@ import static org.apache.sis.test.TestUt
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -203,6 +207,21 @@ public final strictfp class CommonCRSTes
     }
 
     /**
+     * Tests {@link CommonCRS#UTM(double, double)}.
+     *
+     * @since 0.7
+     */
+    @Test
+    @DependsOnMethod("testGeographic")
+    public void testUTM() {
+        final ProjectedCRS crs = CommonCRS.WGS72.UTM(-45, -122);
+        assertEquals("name", "WGS 72 / UTM zone 10S", crs.getName().getCode());
+        final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues();
+        assertEquals(Constants.LATITUDE_OF_ORIGIN, -123, pg.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
+        assertEquals(Constants.FALSE_NORTHING, 10000000, pg.parameter(Constants.FALSE_NORTHING).doubleValue(),   STRICT);
+    }
+
+    /**
      * Tests {@link CommonCRS#forCode(String, String, FactoryException)}.
      *
      * @throws FactoryException If a CRS can not be constructed.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -16,15 +16,22 @@
  */
 package org.apache.sis.referencing;
 
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.PrimeMeridian;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.datum.VerticalDatum;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.internal.util.Constants;
+
+// Test dependencies
 import org.apache.sis.test.mock.GeodeticDatumMock;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
@@ -32,8 +39,8 @@ import org.apache.sis.test.TestCase;
 import org.opengis.test.Validators;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.referencing.cs.HardCodedAxes;
+import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.referencing.datum.HardCodedDatum;
-import org.apache.sis.metadata.iso.citation.Citations;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -48,10 +55,26 @@ import static org.junit.Assert.*;
  * @module
  */
 @DependsOn({
-    org.apache.sis.referencing.crs.DefaultGeographicCRSTest.class
+    org.apache.sis.referencing.crs.DefaultGeographicCRSTest.class,
+    org.apache.sis.internal.referencing.provider.TransverseMercatorTest.class
 })
 public final strictfp class StandardDefinitionsTest extends TestCase {
     /**
+     * Tests {@link StandardDefinitions#createUTM(int, GeographicCRS, double, boolean, CartesianCS)}.
+     *
+     * @since 0.7
+     */
+    @Test
+    @DependsOnMethod("testCreateGeographicCRS")
+    public void testCreateUTM() {
+        final ProjectedCRS crs = StandardDefinitions.createUTM(32610, HardCodedCRS.WGS84, -122, false, HardCodedCS.PROJECTED);
+        assertEquals("name", "WGS 84 / UTM zone 10N", crs.getName().getCode());
+        final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues();
+        assertEquals(Constants.LATITUDE_OF_ORIGIN, -123, pg.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT);
+        assertEquals(Constants.FALSE_NORTHING,        0, pg.parameter(Constants.FALSE_NORTHING).doubleValue(),   STRICT);
+    }
+
+    /**
      * Compares the values created by {@code StandardDefinitions} against hard-coded constants.
      * This method tests the following methods:
      *
@@ -127,10 +150,12 @@ public final strictfp class StandardDefi
      */
     @Test
     public void testCreateAxis() {
-        for (final short code : new short[] {106, 107, 110, 114, 113}) {
+        for (final short code : new short[] {1, 2, 106, 107, 110, 114, 113}) {
             final CoordinateSystemAxis actual = StandardDefinitions.createAxis(code);
             Validators.validate(actual);
             switch (code) {
+                case   1: compare(HardCodedAxes.EASTING,                actual); break;
+                case   2: compare(HardCodedAxes.NORTHING,               actual); break;
                 case 106: compare(HardCodedAxes.GEODETIC_LATITUDE,      actual); break;
                 case 107: compare(HardCodedAxes.GEODETIC_LONGITUDE,     actual); break;
                 case 110: compare(HardCodedAxes.ELLIPSOIDAL_HEIGHT,     actual); break;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MapProjectionTestCase.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -97,7 +97,7 @@ strictfp class MapProjectionTestCase ext
     {
         final Parameters parameters = parameters(provider, ellipse);
         if (centralMeridian  != 0) parameters.parameter(Constants.CENTRAL_MERIDIAN)   .setValue(centralMeridian, NonSI.DEGREE_ANGLE);
-        if (latitudeOfOrigin != 0) parameters.parameter("latitude_of_origin")         .setValue(latitudeOfOrigin);
+        if (latitudeOfOrigin != 0) parameters.parameter(Constants.LATITUDE_OF_ORIGIN) .setValue(latitudeOfOrigin);
         if (standardParallel != 0) parameters.parameter(Constants.STANDARD_PARALLEL_1).setValue(standardParallel);
         if (scaleFactor      != 1) parameters.parameter(Constants.SCALE_FACTOR)       .setValue(scaleFactor);
         if (falseEasting     != 0) parameters.parameter(Constants.FALSE_EASTING)      .setValue(falseEasting);

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -138,6 +138,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.referencing.provider.NTv2Test.class,
     org.apache.sis.internal.referencing.provider.NADCONTest.class,
     org.apache.sis.internal.referencing.provider.MapProjectionTest.class,
+    org.apache.sis.internal.referencing.provider.TransverseMercatorTest.class,
     org.apache.sis.internal.referencing.provider.AllProvidersTest.class,
     org.apache.sis.referencing.operation.transform.InterpolatedTransformTest.class,
     org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransformTest.class,

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -111,6 +111,11 @@ public final class Constants extends Sta
     public static final String CENTRAL_MERIDIAN = "central_meridian";
 
     /**
+     * The OGC parameter name for the latitude of origin.
+     */
+    public static final String LATITUDE_OF_ORIGIN = "latitude_of_origin";
+
+    /**
      * The NetCDF parameter name for the standard parallels.
      */
     public static final String STANDARD_PARALLEL = "standard_parallel";

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java?rev=1724259&r1=1724258&r2=1724259&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Longitude.java [UTF-8] Tue Jan 12 15:28:13 2016
@@ -110,6 +110,8 @@ public final class Longitude extends Ang
      *   <li>±0 are returned unchanged (i.e. the sign of negative and positive zero is preserved)</li>
      * </ul>
      *
+     * Note that the given value should not be greater than 4×10⁸ degrees if a centimetric precision is desired.
+     *
      * @param  λ The longitude value in decimal degrees.
      * @return The given value normalized to the [-180 … 180)° range, or NaN if the given value was NaN of infinite.
      *



Mime
View raw message