sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1724327 - 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 21:34:04 GMT
Author: desruisseaux
Date: Tue Jan 12 21:34:04 2016
New Revision: 1724327

URL: http://svn.apache.org/viewvc?rev=1724327&view=rev
Log:
Complete the support of ProjectedCRS codes in the "AUTO2" namespace.
The support of codes in the "AUTO" namespace is not yet complete, as it is missing the parsing
of units as EPSG code.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.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/provider/TransverseMercatorTest.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/factory/CommonAuthorityFactoryTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1724327&r1=1724326&r2=1724327&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
[UTF-8] Tue Jan 12 21:34:04 2016
@@ -28,9 +28,11 @@ import org.opengis.referencing.cs.Cartes
 import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.Conversion;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.measure.Latitude;
 import org.apache.sis.referencing.Builder;
 
 
@@ -185,24 +187,26 @@ public class GeodeticObjectBuilder exten
      * <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, optionally snapped to a UTM zone</td></tr>
+     *   <tr><td>Latitude of natural origin</td>     <td>Given latitude,
snapped to 0° in the UTM case</td></tr>
+     *   <tr><td>Longitude of natural origin</td>    <td>Given longitude,
optionally snapped to a UTM zone</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  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  isUTM      If {@code true}, the given central meridian will be snapped to
the central meridian of a UTM zone.
+     * @param  latitude   The latitude in the center of the desired projection.
+     * @param  longitude  The longitude in the center of the desired projection.
      * @return {@code this}, for method call chaining.
      * @throws FactoryException if the operation method for the Transverse Mercator projection
can not be obtained.
      */
-    public GeodeticObjectBuilder setTransverseMercator(double centralMeridian, boolean isUTM,
final boolean isSouth)
+    public GeodeticObjectBuilder setTransverseMercator(boolean isUTM, double latitude, double
longitude)
             throws FactoryException
     {
-        setConversionMethod("Transverse_Mercator");
-        setConversionName(TransverseMercator.setParameters(parameters, centralMeridian, isUTM,
isSouth));
+        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));
         return this;
     }
 

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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -29,6 +29,7 @@ import org.apache.sis.parameter.Paramete
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.operation.projection.NormalizedProjection;
 import org.apache.sis.internal.util.Constants;
+import org.apache.sis.math.MathFunctions;
 
 
 /**
@@ -145,7 +146,7 @@ public final class TransverseMercator ex
      * <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>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>
@@ -153,19 +154,21 @@ public final class TransverseMercator ex
      * </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.
-     * @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 longitude, final boolean isUTM, final boolean isSouth)
+            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;
@@ -174,7 +177,7 @@ public final class TransverseMercator ex
         if (zone != 0) {
             name = "UTM zone " + zone + (isSouth ? 'S' : 'N');
         }
-        group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(0, NonSI.DEGREE_ANGLE);
+        group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(latitude,  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);

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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -824,10 +824,15 @@ public enum CommonCRS {
      *       Longitudes outside the [-180 … 180]° range will be rolled as needed before
to compute the zone.</li>
      * </ul>
      *
+     * <div class="note"><b>Warning:</b>
+     * be aware of parameter order! For this method, latitude is first.
+     * This order is for consistency with the non-normalized {@linkplain #geographic() geographic}
CRS
+     * of all items in this {@code CommonCRS} enumeration.</div>
+     *
      * The map projection uses the following parameters:
      *
      * <blockquote><table class="sis">
-     *   <caption>Transverse Mercator parameters</caption>
+     *   <caption>Universal Transverse Mercator (UTM) 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>
@@ -887,7 +892,7 @@ public enum CommonCRS {
                     cs = (CartesianCS) StandardDefinitions.createCoordinateSystem((short)
4400);
                 }
             }
-            crs = StandardDefinitions.createUTM(code, geographic(), longitude, isSouth, cs);
+            crs = StandardDefinitions.createUTM(code, geographic(), latitude, longitude,
cs);
             final ProjectedCRS other;
             synchronized (cachedUTM) {
                 other = cachedUTM.putIfAbsent(key, crs);

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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -129,12 +129,12 @@ final class StandardDefinitions {
      *
      * @param code       The EPSG code, or 0 if none.
      * @param baseCRS    The geographic CRS on which the projected CRS is based.
+     * @param latitude   A latitude in the zone of the desired projection, to be snapped
to 0°.
      * @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 longitude, final boolean isSouth, final CartesianCS derivedCS)
+            final double latitude, final double longitude, final CartesianCS derivedCS)
     {
         final OperationMethod method;
         try {
@@ -145,7 +145,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, longitude, true, isSouth);
+        String name = TransverseMercator.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/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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -21,8 +21,10 @@ import java.util.Set;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Collections;
-import java.util.Arrays;
+import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
 import org.opengis.util.InternationalString;
@@ -45,14 +47,13 @@ import org.opengis.referencing.datum.Eng
 import org.opengis.util.GenericName;
 import org.opengis.util.ScopedName;
 import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
-import org.apache.sis.internal.referencing.provider.TransverseMercator;
 import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.metadata.iso.citation.DefaultCitation;
-import org.apache.sis.internal.simple.SimpleIdentifier;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.math.MathFunctions;
+import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.referencing.cs.AxisFilter;
+import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.CharSequences;
@@ -60,6 +61,9 @@ 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;
+
 
 /**
  * Creates coordinate reference systems in the "{@code OGC}", "{@code CRS}" or {@code "AUTO(2)"}
namespaces.
@@ -174,10 +178,15 @@ import org.apache.sis.util.iso.SimpleInt
  * is the longitude and latitude of a point in the projection centre.
  *
  * <div class="note"><b>Examples:</b>
- * {@code "AUTO2:42003,1,-100,45"}.</div>
+ * {@code "AUTO2:42001,1,-100,45"} identifies a Universal Transverse Mercator (UTM) projection
+ * for a zone containing the point at (45°N, 100°W).</div>
  *
- * Codes in the {@code "AUTO"} namespace are the same than codes in the {@code "AUTO2"} namespace,
- * but with the unit factor omitted.
+ * Codes in the {@code "AUTO"} namespace are the same than codes in the {@code "AUTO2"} namespace,
except that
+ * the {@linkplain org.apache.sis.measure.Units#valueOfEPSG(int) EPSG code} of the desired
unit of measurement
+ * was used instead than the unit factor.
+ * The {@code "AUTO"} namespace was defined in the <cite>Web Map Service</cite>
(WMS) 1.1.1 specification
+ * while the {@code "AUTO2"} namespace is defined in WMS 1.3.0.
+ * In Apache SIS implementation, the unit parameter (either as factor or as EPSG code) is
optional and default to metres.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.7
@@ -185,7 +194,6 @@ import org.apache.sis.util.iso.SimpleInt
  * @module
  *
  * @see CommonCRS
- * @see Citations#OGC
  */
 public class CommonAuthorityFactory extends GeodeticAuthorityFactory implements CRSAuthorityFactory
{
     /**
@@ -226,11 +234,6 @@ public class CommonAuthorityFactory exte
     private final Map<String,Class<?>> codes;
 
     /**
-     * The authority for this factory, created when first needed.
-     */
-    private Citation authority;
-
-    /**
      * The "Computer display" reference system (CRS:1). Created when first needed.
      *
      * @see #displayCRS()
@@ -238,6 +241,11 @@ public class CommonAuthorityFactory exte
     private CoordinateReferenceSystem displayCRS;
 
     /**
+     * The coordinate system for map projection in metres, created when first needed.
+     */
+    private volatile CartesianCS projectedCS;
+
+    /**
      * Constructs a default factory for the {@code CRS} authority.
      *
      * @param nameFactory The factory to use for {@linkplain NameFactory#parseGenericName
parsing} authority codes.
@@ -252,25 +260,18 @@ public class CommonAuthorityFactory exte
      * The authority for this factory is the <cite>Open Geospatial Consortium</cite>.
      *
      * @return The OGC authority.
+     *
+     * @see Citations#OGC
      */
     @Override
-    public synchronized Citation getAuthority() {
-        if (authority == null) {
-            final DefaultCitation c = new DefaultCitation(Citations.OGC);
-            c.setIdentifiers(Arrays.asList(
-                    new SimpleIdentifier(null, Constants.OGC, false),
-                    new SimpleIdentifier(null, Constants.CRS, false)
-            ));
-            c.freeze();
-            authority = c;
-        }
-        return authority;
+    public Citation getAuthority() {
+        return Citations.OGC;
     }
 
     /**
      * Returns {@code true} if the given string if one of the namespaces recognized by this
factory.
      */
-    private static boolean isAuthority(final String namespace) {
+    private static boolean isCodeSpace(final String namespace) {
         if (!namespace.equalsIgnoreCase(Constants.CRS) && !namespace.equalsIgnoreCase(Constants.OGC))
{
             final int s = AUTO2.length() - 1;
             if (!namespace.regionMatches(true, 0, AUTO2, 0, s)) {
@@ -295,7 +296,7 @@ public class CommonAuthorityFactory exte
         final GenericName name = nameFactory.parseGenericName(null, code);
         if (name instanceof ScopedName) {
             final GenericName scope = ((ScopedName) name).path();
-            if (!isAuthority(CharSequences.trimWhitespaces(scope.toString()))) {
+            if (!isCodeSpace(CharSequences.trimWhitespaces(scope.toString()))) {
                 throw new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.UnknownAuthority_1,
scope), Constants.OGC, code);
             }
             code = name.tip().toString();
@@ -392,7 +393,7 @@ public class CommonAuthorityFactory exte
             try {
                 codeValue = Integer.parseInt(localCode);
             } catch (NumberFormatException exception) {
-                throw noSuchAuthorityCode(false, localCode, code, exception);
+                throw noSuchAuthorityCode(localCode, code, exception);
             }
             final int i = codeValue - FIRST_PROJECTION_CODE;
             if (i >= 0 && i < PROJECTION_NAMES.length) {
@@ -437,8 +438,8 @@ public class CommonAuthorityFactory exte
         String complement = null;
         final int startOfParameters = localCode.indexOf(SEPARATOR);
         if (startOfParameters >= 0) {
-            localCode = code.substring(0, CharSequences.skipTrailingWhitespaces(code, 0,
startOfParameters));
-            complement = code.substring(startOfParameters + 1);
+            complement = localCode.substring(startOfParameters + 1);
+            localCode = localCode.substring(0, CharSequences.skipTrailingWhitespaces(localCode,
0, startOfParameters));
         }
         int codeValue = 0;
         double[] parameters = ArraysExt.EMPTY_DOUBLE;
@@ -448,7 +449,7 @@ public class CommonAuthorityFactory exte
                 parameters = CharSequences.parseDoubles(complement, SEPARATOR);
             }
         } catch (NumberFormatException exception) {
-            throw noSuchAuthorityCode(codeValue >= FIRST_PROJECTION_CODE, localCode, code,
exception);
+            throw noSuchAuthorityCode(localCode, code, exception);
         }
         /*
          * At this point we have isolated the code value from the parameters (if any). Verify
the number of arguments.
@@ -482,7 +483,7 @@ public class CommonAuthorityFactory exte
             case Constants.CRS83: crs = CommonCRS.NAD83; break;
             case Constants.CRS27: crs = CommonCRS.NAD27; break;
             case Constants.CRS88: return CommonCRS.Vertical.NAVD88.crs();
-            default: throw noSuchAuthorityCode(false, localCode, code, null);
+            default: throw noSuchAuthorityCode(localCode, code, null);
         }
         return crs.normalizedGeographic();
     }
@@ -497,37 +498,90 @@ public class CommonAuthorityFactory exte
      * @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,
+    @SuppressWarnings("null")
+    private ProjectedCRS createAuto(final String code, final int projection,
             final double factor, final double longitude, final double latitude) throws FactoryException
     {
-        IllegalArgumentException failure = null;
+        Boolean isUTM = null;
+        String method = null;
+        String param  = null;
+        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.
+             * 42003: WGS 84 / Auto Orthographic      —   defined by "Central_Meridian"
and "Latitude_of_Origin".
+             * 42004: WGS 84 / Auto Equirectangular   —   defined by "Central_Meridian"
and "Standard_Parallel_1".
+             * 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;
+            default: throw noSuchAuthorityCode(String.valueOf(projection), code, null);
+        }
+        /*
+         * For the (Universal) Transverse Mercator case (AUTO:42001 and 42002), we delegate
to the CommonCRS
+         * enumeration if possible because CommonCRS will itself delegate to the EPSG factory
if possible.
+         */
+        final CommonCRS datum = CommonCRS.WGS84;
+        final GeographicCRS baseCRS;
+        final ProjectedCRS crs;
+        CartesianCS cs;
         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);
-                    }
+            if (isUTM != null && isUTM) {
+                crs = datum.UTM(latitude, longitude);
+                if (factor == 1) {
                     return crs;
                 }
+                baseCRS = crs.getBaseCRS();
+                cs = crs.getCoordinateSystem();
+            } else {
+                cs = projectedCS;
+                if (cs == null) {
+                    crs = datum.UTM(latitude, longitude);
+                    projectedCS = cs = crs.getCoordinateSystem();
+                    baseCRS = crs.getBaseCRS();
+                } else {
+                    crs = null;
+                    baseCRS = datum.geographic();
+                }
+            }
+            /*
+             * At this point we got a coordinate system with axes in metres.
+             * If the user asked for another unit of measurement, change the axes now.
+             */
+            if (factor != 1) {
+                final Unit<Length> unit = Units.multiply(SI.METRE, factor);
+                cs = (CartesianCS) CoordinateSystems.replaceAxes(cs, new AxisFilter() {
+                    @Override public Unit<?> getUnitReplacement(Unit<?> ignored)
{
+                        assert SI.METRE.equals(ignored) : ignored;
+                        return unit;
+                    }
+                });
+            }
+            /*
+             * Set the projection name, operation method and parameters. The parameters for
the Transverse Mercator
+             * projection are a little bit more tedious to set, so we use a convenience method
for that.
+             */
+            final GeodeticObjectBuilder builder = new GeodeticObjectBuilder();
+            if (isUTM != null) {
+                if (isUTM) {
+                    builder.addName(crs.getName());
+                } // else default to the conversion name, which is "Transverse Mercator".
+                builder.setTransverseMercator(isUTM, latitude, longitude);
+            } else {
+                builder.setConversionMethod(method)
+                       .addName(PROJECTION_NAMES[projection - FIRST_PROJECTION_CODE])
+                       .setParameter(Constants.CENTRAL_MERIDIAN, longitude, NonSI.DEGREE_ANGLE);
+                if (param != null) {
+                    builder.setParameter(param, latitude, NonSI.DEGREE_ANGLE);
+                }
             }
+            return builder.createProjectedCRS(baseCRS, cs);
         } catch (IllegalArgumentException e) {
-            failure = e;
+            throw noSuchAuthorityCode(String.valueOf(projection), code, e);
         }
-        throw noSuchAuthorityCode(true, String.valueOf(projection), code, failure);
     }
 
     /**
@@ -558,13 +612,9 @@ public class CommonAuthorityFactory exte
      * @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 localCode, final String code, final Exception cause)
-    {
-        NoSuchAuthorityCodeException e = new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.NoSuchAuthorityCode_3,
-                Constants.OGC, isAuto ? ProjectedCRS.class : CoordinateReferenceSystem.class,
localCode),
-                Constants.OGC, localCode, code);
-        e.initCause(cause);
-        return e;
+    private static NoSuchAuthorityCodeException noSuchAuthorityCode(String localCode, String
code, Exception cause) {
+        return (NoSuchAuthorityCodeException) new NoSuchAuthorityCodeException(Errors.format(Errors.Keys.NoSuchAuthorityCode_3,
+                Constants.OGC, CoordinateReferenceSystem.class, localCode),
+                Constants.OGC, localCode, code).initCause(cause);
     }
 }

Modified: 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=1724327&r1=1724326&r2=1724327&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java
[UTF-8] Tue Jan 12 21:34:04 2016
@@ -27,6 +27,8 @@ import static org.junit.Assert.*;
 
 /**
  * Tests {@link TransverseMercator} static methods.
+ * 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
@@ -64,15 +66,15 @@ public final strictfp class TransverseMe
     })
     public void testCreate() {
         final ParameterValueGroup p = TransverseMercator.PARAMETERS.createValue();
-        assertEquals("UTM zone 10N", TransverseMercator.setParameters(p, -122, true, false));
+        assertEquals("UTM zone 10N", TransverseMercator.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("Transverse Mercator", TransverseMercator.setParameters(p, -122, false,
false));
+        assertEquals("Transverse Mercator", TransverseMercator.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 10S", TransverseMercator.setParameters(p, -123, false, true));
+        assertEquals("UTM zone 10S", TransverseMercator.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);
     }

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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -219,6 +219,8 @@ public final strictfp class CommonCRSTes
         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);
+        assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.UTM(-45, -122));
+        assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.UTM(+45, -122));
     }
 
     /**

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=1724327&r1=1724326&r2=1724327&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 21:34:04 2016
@@ -67,7 +67,7 @@ public final strictfp class StandardDefi
     @Test
     @DependsOnMethod("testCreateGeographicCRS")
     public void testCreateUTM() {
-        final ProjectedCRS crs = StandardDefinitions.createUTM(32610, HardCodedCRS.WGS84,
-122, false, HardCodedCS.PROJECTED);
+        final ProjectedCRS crs = StandardDefinitions.createUTM(32610, HardCodedCRS.WGS84,
15, -122, 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);

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java?rev=1724327&r1=1724326&r2=1724327&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
[UTF-8] Tue Jan 12 21:34:04 2016
@@ -17,9 +17,13 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Arrays;
+import javax.measure.unit.SI;
+import javax.measure.unit.NonSI;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
 import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.EngineeringCRS;
 import org.opengis.referencing.crs.GeographicCRS;
@@ -27,7 +31,9 @@ import org.opengis.referencing.crs.Proje
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.datum.Datum;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.referencing.provider.TransverseMercator;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.io.wkt.Convention;
@@ -38,7 +44,7 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.apache.sis.test.MetadataAssert.*;
+import static org.apache.sis.test.ReferencingAssert.*;
 
 
 /**
@@ -86,12 +92,25 @@ public final strictfp class CommonAuthor
     }
 
     /**
+     * Tests {@link CommonAuthorityFactory#getDescriptionText(String)}.
+     *
+     * @throws FactoryException if an error occurred while creating a CRS.
+     */
+    @Test
+    @DependsOnMethod({"testCRS84", "testAuto42001"})
+    public void testDescription() throws FactoryException {
+        assertEquals("WGS 84",                factory.getDescriptionText("CRS:84").toString());
+        assertEquals("WGS 84 / Auto UTM",     factory.getDescriptionText("AUTO:42001").toString());
+        assertEquals("WGS 84 / UTM zone 10S", factory.getDescriptionText("AUTO:42001,-124,-10").toString());
+    }
+
+    /**
      * Checks the value returned by {@link CommonAuthorityFactory#getAuthority()}.
      */
     @Test
     public void testAuthority() {
         final Citation authority = factory.getAuthority();
-        assertTrue (Citations.identifierMatches(authority, "CRS"));
+        assertFalse(Citations.identifierMatches(authority, "CRS"));
         assertTrue (Citations.identifierMatches(authority, "OGC"));
         assertFalse(Citations.identifierMatches(authority, "OGP"));
         assertFalse(Citations.identifierMatches(authority, "EPSG"));
@@ -105,7 +124,6 @@ public final strictfp class CommonAuthor
      * @throws FactoryException if an error occurred while creating a CRS.
      */
     @Test
-    @DependsOnMethod("testAuthority")
     public void testCRS84() throws FactoryException {
         GeographicCRS crs = factory.createGeographicCRS("CRS:84");
         assertSame   (crs,  factory.createGeographicCRS("84"));
@@ -124,7 +142,6 @@ public final strictfp class CommonAuthor
      * @throws FactoryException if an error occurred while creating a CRS.
      */
     @Test
-    @DependsOnMethod("testAuthority")
     public void testCRS83() throws FactoryException {
         GeographicCRS crs = factory.createGeographicCRS("CRS:83");
         assertSame   (crs,  factory.createGeographicCRS("83"));
@@ -141,7 +158,6 @@ public final strictfp class CommonAuthor
      * @throws FactoryException if an error occurred while creating a CRS.
      */
     @Test
-    @DependsOnMethod("testAuthority")
     public void testCRS88() throws FactoryException {
         VerticalCRS crs = factory.createVerticalCRS("CRS:88");
         assertSame (crs,  factory.createVerticalCRS("88"));
@@ -156,16 +172,83 @@ public final strictfp class CommonAuthor
      * @throws FactoryException if an error occurred while creating a CRS.
      */
     @Test
-    @DependsOnMethod("testAuthority")
     public void testCRS1() throws FactoryException {
         EngineeringCRS crs = factory.createEngineeringCRS("CRS:1");
-        assertSame (crs,  factory.createEngineeringCRS("1"));
-        assertSame (crs,  factory.createEngineeringCRS("CRS1"));
-        assertSame (crs,  factory.createEngineeringCRS("CRS:CRS 1"));
+        assertSame    (crs,  factory.createEngineeringCRS("1"));
+        assertSame    (crs,  factory.createEngineeringCRS("CRS1"));
+        assertSame    (crs,  factory.createEngineeringCRS("CRS:CRS 1"));
         assertAxisDirectionsEqual("CS", crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.SOUTH);
     }
 
     /**
+     * Tests {@link CommonAuthorityFactory#createProjectedCRS(String)} with the {@code "AUTO:42001"}
code.
+     *
+     * @throws FactoryException if an error occurred while creating a CRS.
+     */
+    @Test
+    public void testAuto42001() throws FactoryException {
+        final ProjectedCRS crs = factory.createProjectedCRS("AUTO:42001,-123,0");
+        assertSame("With other coord.",   crs, factory.createProjectedCRS("AUTO : 42001,
-122, 10 "));
+        assertSame("Omitting namespace.", crs, factory.createProjectedCRS(" 42001, -122 ,
10 "));
+        assertSame("With explicit unit.", crs, factory.createProjectedCRS("AUTO2 :  42001,
1, -122 , 10 "));
+        assertSame("When the given parameters match exactly the UTM central meridian and
latitude of origin,"
+                + " the CRS created by AUTO:42002 should be the same than the CRS created
by AUTO:42001.",
+                crs, factory.createProjectedCRS("AUTO2:42002,1,-123,0"));
+
+        assertEpsgNameAndIdentifierEqual("WGS 84 / UTM zone 10N", 32610, crs);
+        final ParameterValueGroup p = crs.getConversionFromBase().getParameterValues();
+        assertEquals(TransverseMercator.NAME, crs.getConversionFromBase().getMethod().getName().getCode());
+        assertAxisDirectionsEqual("CS", crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.NORTH);
+        assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN)
 .doubleValue(), STRICT);
+        assertEquals(Constants.LATITUDE_OF_ORIGIN,  0, p.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(),
STRICT);
+        assertEquals(Constants.FALSE_NORTHING,      0, p.parameter(Constants.FALSE_NORTHING)
   .doubleValue(), STRICT);
+        assertEquals("axis[0].unit", SI.METRE, crs.getCoordinateSystem().getAxis(0).getUnit());
+        try {
+            factory.createObject("AUTO:42001");
+            fail("Should not have accepted incomplete code.");
+        } catch (NoSuchAuthorityCodeException e) {
+            assertEquals("42001", e.getAuthorityCode());
+        }
+    }
+
+    /**
+     * Tests {@link CommonAuthorityFactory#createProjectedCRS(String)} with the same {@code
"AUTO:42001"} code
+     * than {@link #testAuto42001()} except that axes are feet.
+     *
+     * @throws FactoryException if an error occurred while creating a CRS.
+     */
+    @Test
+    @DependsOnMethod("testAuto42001")
+    public void testAuto42001_foot() throws FactoryException {
+        final ProjectedCRS crs = factory.createProjectedCRS("AUTO2:42001, 0.3048, -123, 0");
+        assertEquals("name", "WGS 84 / UTM zone 10N", crs.getName().getCode());
+        assertTrue("Expected no EPSG identifier because the axes are not in metres.", crs.getIdentifiers().isEmpty());
+        assertEquals("axis[0].unit", NonSI.FOOT, crs.getCoordinateSystem().getAxis(0).getUnit());
+    }
+
+    /**
+     * Tests {@link CommonAuthorityFactory#createProjectedCRS(String)} with the {@code "AUTO:42002"}
code.
+     *
+     * @throws FactoryException if an error occurred while creating a CRS.
+     */
+    @Test
+    @DependsOnMethod("testAuto42001")
+    public void testAuto42002() throws FactoryException {
+        final ProjectedCRS crs = factory.createProjectedCRS("AUTO:42002,-122,10");
+        assertSame("Omitting namespace.", crs, factory.createProjectedCRS(" 42002, -122 ,
10 "));
+        assertSame("With explicit unit.", crs, factory.createProjectedCRS("AUTO2 :  42002,
1, -122 , 10 "));
+        assertEquals("name", "Transverse Mercator", crs.getName().getCode());
+        assertTrue("Expected no EPSG identifier.", crs.getIdentifiers().isEmpty());
+
+        final ParameterValueGroup p = crs.getConversionFromBase().getParameterValues();
+        assertEquals(TransverseMercator.NAME, crs.getConversionFromBase().getMethod().getName().getCode());
+        assertAxisDirectionsEqual("CS", crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.NORTH);
+        assertEquals(Constants.CENTRAL_MERIDIAN, -122, p.parameter(Constants.CENTRAL_MERIDIAN)
 .doubleValue(), STRICT);
+        assertEquals(Constants.LATITUDE_OF_ORIGIN, 10, p.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(),
STRICT);
+        assertEquals(Constants.FALSE_NORTHING,      0, p.parameter(Constants.FALSE_NORTHING)
   .doubleValue(), STRICT);
+    }
+
+    /**
      * Tests the WKT formatting. The main purpose of this test is to ensure that
      * the authority name is "CRS" and not "Web Map Service CRS".
      *

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1724327&r1=1724326&r2=1724327&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8]
(original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8]
Tue Jan 12 21:34:04 2016
@@ -531,6 +531,7 @@ public final class Units extends Static
      *       <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
      *       <tr><td>9001</td><td>metre</td></tr>
      *       <tr><td>9002</td><td>foot</td></tr>
+     *       <tr><td>9003</td><td>US survey foot</td></tr>
      *       <tr><td>9030</td><td>nautical mile</td></tr>
      *       <tr><td>9036</td><td>kilometre</td></tr>
      *     </table></td>
@@ -564,6 +565,7 @@ public final class Units extends Static
             case 1040: return SI   .SECOND;
             case 9001: return SI   .METRE;
             case 9002: return NonSI.FOOT;
+            case 9003: return NonSI.FOOT_SURVEY_US;
             case 9030: return NonSI.NAUTICAL_MILE;
             case 9036: return SI   .KILOMETRE;
             case 9101: return SI   .RADIAN;




Mime
View raw message