Author: desruisseaux
Date: Wed Jan 22 14:00:08 2014
New Revision: 1560354

URL: http://svn.apache.org/r1560354
Log:
Added GeodeticObjects.geocentric() method.

Modified:
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
    
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java?rev=1560354&r1=1560353&r2=1560354&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
 [UTF-8] Wed Jan 22 14:00:08 2014
@@ -19,6 +19,7 @@ package org.apache.sis.io.wkt;
 import javax.measure.unit.SI;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CartesianCS;
+import org.apache.sis.referencing.GeodeticObjects;
 import org.apache.sis.referencing.cs.DefaultCartesianCS;
 import org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis;
 import org.apache.sis.util.Static;
@@ -55,15 +56,16 @@ final class Legacy extends Static {
             new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Z"), "Z", 
AxisDirection.NORTH, SI.METRE));
 
     /**
-     * The standard three-dimensional Cartesian CS as defined by ISO 19111.
+     * Do not allow instantiation of this class.
      */
-    @Deprecated
-    static CartesianCS STANDARD; // TODO: Not supported yet.
+    private Legacy() {
+    }
 
     /**
-     * Do not allow instantiation of this class.
+     * The standard three-dimensional Cartesian CS as defined by ISO 19111.
      */
-    private Legacy() {
+    private static CartesianCS standard() {
+        return (CartesianCS) 
GeodeticObjects.WGS84.geocentric().getCoordinateSystem();
     }
 
     /**
@@ -77,7 +79,7 @@ final class Legacy extends Static {
      *         or {@code cs} if the CS axes should be used as-is.
      */
     static CartesianCS replace(final CartesianCS cs, final boolean toLegacy) {
-        final CartesianCS check = toLegacy ? STANDARD : LEGACY;
+        final CartesianCS check = toLegacy ? standard() : LEGACY;
         final int dimension = check.getDimension();
         if (cs.getDimension() != dimension) {
             return cs;
@@ -87,6 +89,6 @@ final class Legacy extends Static {
                 return cs;
             }
         }
-        return toLegacy ? LEGACY : STANDARD;
+        return toLegacy ? LEGACY : standard();
     }
 }

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java?rev=1560354&r1=1560353&r2=1560354&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
 [UTF-8] Wed Jan 22 14:00:08 2014
@@ -29,8 +29,10 @@ import org.opengis.referencing.crs.Geode
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.cs.TimeCS;
 import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.datum.Ellipsoid;
@@ -50,6 +52,7 @@ import org.apache.sis.referencing.cs.Def
 import org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis;
 import org.apache.sis.referencing.crs.DefaultTemporalCRS;
 import org.apache.sis.referencing.crs.DefaultVerticalCRS;
+import org.apache.sis.referencing.crs.DefaultGeocentricCRS;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.resources.Vocabulary;
@@ -121,7 +124,7 @@ public enum GeodeticObjects {
      *   <tr><th>Ellipsoid axes unit:</th>     <td>{@link SI#METRE}</td></tr>
      * </table></blockquote>
      */
-    WGS84((short) 4326, (short) 6326, (short) 7030),
+    WGS84((short) 4326, (short) 4978, (short) 6326, (short) 7030),
 
     /**
      * World Geodetic System 1972.
@@ -137,7 +140,7 @@ public enum GeodeticObjects {
      *   <tr><th>Ellipsoid axes unit:</th>     <td>{@link SI#METRE}</td></tr>
      * </table></blockquote>
      */
-    WGS72((short) 4322, (short) 6322, (short) 7043),
+    WGS72((short) 4322, (short) 4984, (short) 6322, (short) 7043),
 
     /**
      * European Terrestrial Reference System 1989.
@@ -159,7 +162,7 @@ public enum GeodeticObjects {
      *        The <cite>Web Map Server</cite> <code>"CRS:83"</code> authority 
code uses the NAD83 datum,
      *        while the <code>"IGNF:MILLER"</code> authority code uses the 
GRS80 datum.}
      */
-    ETRS89((short) 4258, (short) 6258, (short) 7019),
+    ETRS89((short) 4258, (short) 4936, (short) 6258, (short) 7019),
 
     /**
      * North American Datum 1983.
@@ -182,7 +185,7 @@ public enum GeodeticObjects {
      *        The <cite>Web Map Server</cite> <code>"CRS:83"</code> authority 
code uses the NAD83 datum,
      *        while the <code>"IGNF:MILLER"</code> authority code uses the 
GRS80 datum.}
      */
-    NAD83((short) 4269, (short) 6269, (short) 7019),
+    NAD83((short) 4269, (short) 0, (short) 6269, (short) 7019),
 
     /**
      * North American Datum 1927.
@@ -198,7 +201,7 @@ public enum GeodeticObjects {
      *   <tr><th>Ellipsoid axes unit:</th>     <td>{@link SI#METRE}</td></tr>
      * </table></blockquote>
      */
-    NAD27((short) 4267, (short) 6267, (short) 7008),
+    NAD27((short) 4267, (short) 0, (short) 6267, (short) 7008),
 
     /**
      * European Datum 1950.
@@ -214,7 +217,7 @@ public enum GeodeticObjects {
      *   <tr><th>Ellipsoid axes unit:</th>     <td>{@link SI#METRE}</td></tr>
      * </table></blockquote>
      */
-    ED50((short) 4230, (short) 6230, (short) 7022),
+    ED50((short) 4230, (short) 0, (short) 6230, (short) 7022),
 
     /**
      * Unspecified datum based upon the GRS 1980 Authalic Sphere. Spheres use 
a simpler algorithm for
@@ -232,7 +235,7 @@ public enum GeodeticObjects {
      *
      * @see 
org.apache.sis.referencing.datum.DefaultEllipsoid#getAuthalicRadius()
      */
-    SPHERE((short) 4047, (short) 6047, (short) 7048);
+    SPHERE((short) 4047, (short) 0, (short) 6047, (short) 7048);
 
     /**
      * The EPSG code of the geographic CRS.
@@ -240,6 +243,11 @@ public enum GeodeticObjects {
     final short geographic;
 
     /**
+     * The EPSG code of the geocentric CRS, or 0 if none.
+     */
+    final short geocentric;
+
+    /**
      * The EPSG code of the datum. The value is often {@link #geographic} + 
2000,
      * but it doesn't have to be always the case.
      */
@@ -262,17 +270,26 @@ public enum GeodeticObjects {
      *
      * @see #normalizedGeographic()
      */
-    private transient volatile GeographicCRS normalizedGeographic;
+    private transient volatile GeographicCRS cachedNormalized;
+
+    /**
+     * The geocentric CRS, created when first needed.
+     *
+     * @see #geocentric()
+     */
+    private transient volatile GeocentricCRS cachedGeocentric;
 
     /**
      * Creates a new constant for the given EPSG or SIS codes.
      *
      * @param geographic The EPSG code for the geographic CRS.
+     * @param geocentric The EPSG code of the geocentric CRS, or 0 if none.
      * @param datum      The EPSG code for the datum.
      * @param ellipsoid  The EPSG code for the ellipsoid.
      */
-    private GeodeticObjects(final short geographic, final short datum, final 
short ellipsoid) {
+    private GeodeticObjects(final short geographic, final short geocentric, 
final short datum, final short ellipsoid) {
         this.geographic = geographic;
+        this.geocentric = geocentric;
         this.datum      = datum;
         this.ellipsoid  = ellipsoid;
     }
@@ -295,8 +312,9 @@ public enum GeodeticObjects {
      * Invoked by when the cache needs to be cleared after a classpath change.
      */
     synchronized void clear() {
-        cached = null;
-        normalizedGeographic = null;
+        cached           = null;
+        cachedNormalized = null;
+        cachedGeocentric = null;
     }
 
     /**
@@ -350,14 +368,14 @@ public enum GeodeticObjects {
      * @see AxesConvention#NORMALIZED
      */
     public GeographicCRS normalizedGeographic() {
-        GeographicCRS object = normalizedGeographic;
+        GeographicCRS object = cachedNormalized;
         if (object == null) {
             DefaultGeographicCRS crs = 
DefaultGeographicCRS.castOrCopy(geographic());
             crs = crs.forConvention(AxesConvention.RIGHT_HANDED); // 
Equivalent to NORMALIZED in our cases, but faster.
             synchronized (this) {
-                object = normalizedGeographic;
+                object = cachedNormalized;
                 if (object == null) {
-                    normalizedGeographic = object = crs;
+                    cachedNormalized = object = crs;
                 }
             }
         }
@@ -420,6 +438,62 @@ public enum GeodeticObjects {
     }
 
     /**
+     * Returns the geocentric CRS using a Cartesian coordinate system. Axis 
units are metres.
+     * The following table summarizes the coordinate reference systems known 
to this class,
+     * together with an enumeration value that can be used for fetching that 
CRS:
+     *
+     * <blockquote><table class="sis">
+     *   <tr><th>Name or alias</th>            <th>Enum</th>            
<th>EPSG</th></tr>
+     *   <tr><td>ED50</td>                     <td>{@link #ED50}</td>   
<td></td></tr>
+     *   <tr><td>ETRS89</td>                   <td>{@link #ETRS89}</td> 
<td>4936</td></tr>
+     *   <tr><td>NAD27</td>                    <td>{@link #NAD27}</td>  
<td></td></tr>
+     *   <tr><td>NAD83</td>                    <td>{@link #NAD83}</td>  
<td></td></tr>
+     *   <tr><td>GRS 1980 Authalic Sphere</td> <td>{@link #SPHERE}</td> 
<td></td></tr>
+     *   <tr><td>WGS 72</td>                   <td>{@link #WGS72}</td>  
<td>4984</td></tr>
+     *   <tr><td>WGS 84</td>                   <td>{@link #WGS84}</td>  
<td>4978</td></tr>
+     * </table></blockquote>
+     *
+     * @return The geocentric CRS associated to this enum.
+     *
+     * @see CRS#forCode(String)
+     * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS
+     */
+    public GeocentricCRS geocentric() {
+        GeocentricCRS object = cachedGeocentric;
+        if (object == null) {
+            synchronized (this) {
+                object = cachedGeocentric;
+                if (object == null) {
+                    if (geocentric != 0) {
+                        final CRSAuthorityFactory factory = crsFactory();
+                        if (factory != null) try {
+                            cachedGeocentric = object = 
factory.createGeocentricCRS(String.valueOf(geocentric));
+                            return object;
+                        } catch (FactoryException e) {
+                            failure(this, "geocentric", e);
+                        }
+                    }
+                    /*
+                     * All constants defined in this enumeration use the same 
coordinate system, EPSG:6500.
+                     * We will arbitrarily create this CS only for WGS84 (the 
most frequently created CRS),
+                     * and share that CS instance for all other constants.
+                     */
+                    final CartesianCS cs;
+                    if (this == WGS84) {
+                        cs = (CartesianCS) 
StandardDefinitions.createCoordinateSystem((short) 6500);
+                    } else {
+                        cs = (CartesianCS) 
WGS84.geocentric().getCoordinateSystem();
+                    }
+                    // Use same name and datum than the geographic CRS.
+                    final GeographicCRS base = geographic();
+                    return new 
DefaultGeocentricCRS(IdentifiedObjects.getProperties(base), base.getDatum(), 
cs);
+                }
+            }
+        }
+        return object;
+    }
+
+    /**
      * Returns the geodetic datum associated to this geodetic object.
      * The following table summarizes the datums known to this class,
      * together with an enumeration value that can be used for fetching that 
datum:
@@ -435,7 +509,7 @@ public enum GeodeticObjects {
      *   <tr><td>World Geodetic System 1984</td>                        
<td>{@link #WGS84}</td>  <td>6326</td></tr>
      * </table></blockquote>
      *
-     * @return The geodetic datum associated to this constant.
+     * @return The geodetic datum associated to this enum.
      *
      * @see org.apache.sis.referencing.datum.DefaultGeodeticDatum
      */
@@ -475,7 +549,7 @@ public enum GeodeticObjects {
      *   <tr><td>World Geodetic System (WGS) 1984</td> <td>{@link #WGS84}</td> 
 <td>7030</td></tr>
      * </table></blockquote>
      *
-     * @return The ellipsoid associated to this constant.
+     * @return The ellipsoid associated to this enum.
      *
      * @see org.apache.sis.referencing.datum.DefaultEllipsoid
      */
@@ -514,7 +588,7 @@ public enum GeodeticObjects {
      *   <tr><td>Greenwich</td>     <td>{@link #WGS84}</td> <td>8901</td></tr>
      * </table></blockquote>
      *
-     * @return The prime meridian associated to this constant.
+     * @return The prime meridian associated to this enum.
      *
      * @see org.apache.sis.referencing.datum.DefaultPrimeMeridian
      */
@@ -759,7 +833,7 @@ public enum GeodeticObjects {
          *   <tr><td>Other surface</td>             <td>{@link 
#OTHER_SURFACE}</td>      <td></td></tr>
          * </table></blockquote>
          *
-         * @return The CRS associated to this constant.
+         * @return The CRS associated to this enum.
          *
          * @see DefaultVerticalCRS
          */
@@ -823,7 +897,7 @@ public enum GeodeticObjects {
          *   <tr><td>Other surface</td>             <td>{@link 
#OTHER_SURFACE}</td>      <td></td></tr>
          * </table></blockquote>
          *
-         * @return The datum associated to this constant.
+         * @return The datum associated to this enum.
          *
          * @see DefaultVerticalDatum
          */
@@ -1004,7 +1078,7 @@ public enum GeodeticObjects {
          *   <tr><td>Unix/POSIX or Java</td> <td>{@link #UNIX}</td></tr>
          * </table></blockquote>
          *
-         * @return The CRS associated to this constant.
+         * @return The CRS associated to this enum.
          *
          * @see DefaultTemporalCRS
          */
@@ -1072,7 +1146,7 @@ public enum GeodeticObjects {
          *   <tr><td>Unix/POSIX or Java</td> <td>{@link #UNIX}</td></tr>
          * </table></blockquote>
          *
-         * @return The datum associated to this constant.
+         * @return The datum associated to this enum.
          *
          * @see DefaultTemporalDatum
          */

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1560354&r1=1560353&r2=1560354&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
 [UTF-8] Wed Jan 22 14:00:08 2014
@@ -41,6 +41,7 @@ import org.apache.sis.referencing.datum.
 import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
 import org.apache.sis.referencing.datum.DefaultVerticalDatum;
 import org.apache.sis.referencing.cs.DefaultVerticalCS;
+import org.apache.sis.referencing.cs.DefaultCartesianCS;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
 import org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
@@ -230,22 +231,35 @@ final class StandardDefinitions {
      * @param  code The EPSG code.
      * @return The coordinate system for the given code.
      */
+    @SuppressWarnings("fallthrough")
     static CoordinateSystem createCoordinateSystem(final short code) {
         final String name;
-        short xc, yc, zc = 0; // Not necessarily (long, lat) order.
+        final int dim;  // Number of dimension.
+        short axisCode; // Code of first axis + dim (or code after the last 
axis).
+        boolean isCartesian = false;
         switch (code) {
-            case 6422: name = "Ellipsoidal 2D"; xc = 106; yc = 107;           
break;
-            case 6423: name = "Ellipsoidal 3D"; xc = 108; yc = 109; zc = 110; 
break;
+            case 6422: name = "Ellipsoidal 2D"; dim = 2; axisCode = 108; break;
+            case 6423: name = "Ellipsoidal 3D"; dim = 3; axisCode = 111; break;
+            case 6500: name = "Earth centred";  dim = 3; axisCode = 118; 
isCartesian = true; break;
             default:   throw new AssertionError(code);
         }
         final Map<String,?> properties = properties(code, name, null, false);
-        final CoordinateSystemAxis xAxis = createAxis(xc);
-        final CoordinateSystemAxis yAxis = createAxis(yc);
-        if (zc != 0) {
-            final CoordinateSystemAxis zAxis = createAxis(zc);
+        CoordinateSystemAxis xAxis = null, yAxis = null, zAxis = null;
+        switch (dim) {
+            default: throw new AssertionError(dim);
+            case 3:  zAxis = createAxis(--axisCode);
+            case 2:  yAxis = createAxis(--axisCode);
+            case 1:  xAxis = createAxis(--axisCode);
+            case 0:  break;
+        }
+        if (isCartesian) {
+            return new DefaultCartesianCS(properties, xAxis, yAxis, zAxis);
+        }
+        if (zAxis != null) {
             return new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis);
+        } else {
+            return new DefaultEllipsoidalCS(properties, xAxis, yAxis);
         }
-        return new DefaultEllipsoidalCS(properties, xAxis, yAxis);
     }
 
     /**
@@ -256,12 +270,13 @@ final class StandardDefinitions {
      */
     static CoordinateSystemAxis createAxis(final short code) {
         final String name, abrv;
-        final Unit<?> unit;
+        Unit<?> unit = SI.METRE;
         double min = Double.NEGATIVE_INFINITY;
         double max = Double.POSITIVE_INFINITY;
         RangeMeaning rm = null;
         final AxisDirection dir;
         switch (code) {
+            case 108:  // Used in Ellipsoidal 3D.
             case 106:  name = "Geodetic latitude";
                        abrv = "φ";
                        unit = NonSI.DEGREE_ANGLE;
@@ -270,6 +285,7 @@ final class StandardDefinitions {
                        max  = Latitude.MAX_VALUE;
                        rm   = RangeMeaning.EXACT;
                        break;
+            case 109:  // Used in Ellipsoidal 3D.
             case 107:  name = "Geodetic longitude";
                        abrv = "λ";
                        unit = NonSI.DEGREE_ANGLE;
@@ -280,19 +296,28 @@ final class StandardDefinitions {
                        break;
             case 110:  name = "Ellipsoidal height";
                        abrv = "h";
-                       unit = SI.METRE;
                        dir  = AxisDirection.UP;
                        break;
             case 114:  name = "Gravity-related height";
                        abrv = "H";
-                       unit = SI.METRE;
                        dir  = AxisDirection.UP;
                        break;
             case 113:  name = "Depth";
                        abrv = "D";
-                       unit = SI.METRE;
                        dir  = AxisDirection.DOWN;
                        break;
+            case 115:  name = "Geocentric X";
+                       abrv = "X";
+                       dir  = AxisDirection.GEOCENTRIC_X;
+                       break;
+            case 116:  name = "Geocentric Y";
+                       abrv = "Y";
+                       dir  = AxisDirection.GEOCENTRIC_Y;
+                       break;
+            case 117:  name = "Geocentric Z";
+                       abrv = "Z";
+                       dir  = AxisDirection.GEOCENTRIC_Z;
+                       break;
             default:   throw new AssertionError(code);
         }
         return new DefaultCoordinateSystemAxis(properties(code, name, null, 
false), abrv, dir, unit, min, max, rm);

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java?rev=1560354&r1=1560353&r2=1560354&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java
 [UTF-8] Wed Jan 22 14:00:08 2014
@@ -20,6 +20,8 @@ import java.util.Date;
 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.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.datum.TemporalDatum;
 import org.opengis.referencing.datum.VerticalDatum;
@@ -76,6 +78,22 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests the {@link GeodeticObjects#geocentric()} method.
+     */
+    @Test
+    public void testGeocentric() {
+        final GeocentricCRS crs = GeodeticObjects.WGS72.geocentric();
+        assertEquals("WGS 72", crs.getName().getCode());
+        final CoordinateSystem cs = crs.getCoordinateSystem();
+        final String name = cs.getName().getCode();
+        assertTrue(name, name.startsWith("Earth centred"));
+        assertEquals("dimension", 3, cs.getDimension());
+        assertEquals(AxisDirection.GEOCENTRIC_X, cs.getAxis(0).getDirection());
+        assertEquals(AxisDirection.GEOCENTRIC_Y, cs.getAxis(1).getDirection());
+        assertEquals(AxisDirection.GEOCENTRIC_Z, cs.getAxis(2).getDirection());
+    }
+
+    /**
      * Verifies the vertical datum enumeration.
      */
     @Test


Reply via email to