You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/06/30 13:25:45 UTC

svn commit: r1688429 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/test/java/org/apache/sis/io/wkt/ sis-utility/src/main/java/org/apache/sis/measure/

Author: desruisseaux
Date: Tue Jun 30 11:25:44 2015
New Revision: 1688429

URL: http://svn.apache.org/r1688429
Log:
WKT 2: test and fix parsing of ProjectedCRS elements.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Transliterator.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java?rev=1688429&r1=1688428&r2=1688429&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] Tue Jun 30 11:25:44 2015
@@ -196,7 +196,7 @@ abstract class AbstractParser implements
             if (cause instanceof FactoryException) {
                 throw (FactoryException) cause;
             }
-            throw new FactoryException(exception);
+            throw new FactoryException(exception.getMessage(), exception);
         }
     }
 

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1688429&r1=1688428&r2=1688429&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Tue Jun 30 11:25:44 2015
@@ -339,7 +339,7 @@ final class GeodeticObjectParser extends
             throws ParseException
     {
         CoordinateReferenceSystem crs;
-        if ((crs = parseGeodeticCRS    (FIRST, element)) == null &&
+        if ((crs = parseGeodeticCRS    (FIRST, element, null)) == null &&
             (crs = parseProjectedCRS   (FIRST, element)) == null &&
             (crs = parseVerticalCRS    (FIRST, element)) == null &&
             (crs = parseTimeCRS        (FIRST, element)) == null &&
@@ -1010,8 +1010,11 @@ final class GeodeticObjectParser extends
         }
         final String name      = element.pullString("name");
         final double longitude = element.pullDouble("longitude");
-        if (angularUnit == null) {
-            throw element.missingComponent(WKTKeywords.AngleUnit);
+        final Unit<Angle> unit = parseScaledUnit(element, WKTKeywords.AngleUnit, SI.RADIAN);
+        if (unit != null) {
+            angularUnit = unit;
+        } else if (angularUnit == null) {
+            throw parent.missingComponent(WKTKeywords.AngleUnit);
         }
         try {
             return datumFactory.createPrimeMeridian(parseMetadataAndClose(element, name), longitude, angularUnit);
@@ -1134,7 +1137,6 @@ final class GeodeticObjectParser extends
         final String  methodName = element.pullString("method");
         Map<String,?> properties = parseMetadataAndClose(element, methodName);
         final Identifier id      = toIdentifier(properties.remove(IdentifiedObject.IDENTIFIERS_KEY)); // See NOTE 2.
-
         /*
          * The map projection method may be specified by an EPSG identifier (or any other authority),
          * which is preferred to the method name since the later is potentially ambiguous. However not
@@ -1364,15 +1366,17 @@ final class GeodeticObjectParser extends
      *     GEOCCS["<name>", <datum>, <prime meridian>, <linear unit> {,<axis> ,<axis> ,<axis>} {,<authority>}]
      * }
      *
-     * @param  mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  mode   {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
      * @param  parent The parent element.
+     * @param  csType The default coordinate system type, or {@code null} if unknown.
+     *                Should be non-null only when parsing a {@link GeneralDerivedCRS#getBaseCRS()} component.
      * @return The {@code "GeodeticCRS"} element as a {@link GeographicCRS} or {@link GeocentricCRS} object.
      * @throws ParseException if the {@code "GeodeticCRS"} element can not be parsed.
      *
      * @see org.apache.sis.referencing.crs.DefaultGeographicCRS#formatTo(Formatter)
      * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS#formatTo(Formatter)
      */
-    private GeodeticCRS parseGeodeticCRS(final int mode, final Element parent) throws ParseException {
+    private GeodeticCRS parseGeodeticCRS(final int mode, final Element parent, String csType) throws ParseException {
         final Element element = parent.pullElement(mode,
                 WKTKeywords.GeodeticCRS,    // [0]  WKT 2
                 WKTKeywords.GeodCRS,        // [1]  WKT 2
@@ -1383,17 +1387,26 @@ final class GeodeticObjectParser extends
             return null;
         }
         final boolean     isWKT1;
-        final String      csType;
         final Unit<Angle> angularUnit;
-        final Unit<?>     defaultUnit;
+              Unit<?>     defaultUnit;
         final int         dimension;
         switch (element.getKeywordIndex()) {
             default: {      // WKT2 element.
                 isWKT1      = false;
-                csType      = null;
                 defaultUnit = parseUnit(element);
                 angularUnit = Units.isAngular(defaultUnit) ? defaultUnit.asType(Angle.class) : NonSI.DEGREE_ANGLE;
                 dimension   = 2;
+                if (defaultUnit == null) {
+                    /*
+                     * A UNIT[…] is mandatory either in the CoordinateSystem as a whole (defaultUnit != null),
+                     * or inside each AXIS[…] component (defaultUnit == null). An exception to this rule is when
+                     * parsing a BaseGeodCRS inside a ProjectedCRS or DerivedCRS, in which case axes are omitted.
+                     * We recognize those cases by a non-null 'csType' given in argument to this method.
+                     */
+                    if (WKTKeywords.ellipsoidal.equals(csType)) {
+                        defaultUnit = NonSI.DEGREE_ANGLE;   // For BaseGeodCRS in ProjectedCRS.
+                    }
+                }
                 break;
             }
             case 3: {       // WKT1 "GeogCS" element.
@@ -1534,7 +1547,7 @@ final class GeodeticObjectParser extends
         }
         final boolean     isWKT1 = element.getKeywordIndex() == 3;  // Index of "ProjCS" above.
         final String      name   = element.pullString("name");
-        final GeodeticCRS geoCRS = parseGeodeticCRS(MANDATORY, element);
+        final GeodeticCRS geoCRS = parseGeodeticCRS(MANDATORY, element, WKTKeywords.ellipsoidal);
         if (!(geoCRS instanceof GeographicCRS)) {
             throw new LocalizedParseException(errorLocale, Errors.Keys.IllegalCRSType_1,
                     new Object[] {geoCRS.getClass()}, element.offset);

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Transliterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Transliterator.java?rev=1688429&r1=1688428&r2=1688429&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Transliterator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Transliterator.java [UTF-8] Tue Jun 30 11:25:44 2015
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.io.wkt;
 
+import java.util.Map;
+import java.util.HashMap;
 import java.io.Serializable;
 import org.opengis.referencing.cs.PolarCS;
 import org.opengis.referencing.cs.SphericalCS;
@@ -99,6 +101,25 @@ public abstract class Transliterator imp
     private static final long serialVersionUID = 7115456393795045932L;
 
     /**
+     * Default names to associate to axis directions in a Cartesian coordinate system.
+     * Those names do not apply to other kind of coordinate systems.
+     *
+     * <p>For thread safety reasons, this map shall not be modified after construction.</p>
+     */
+    private static final Map<AxisDirection,String> CARTESIAN;
+    static {
+        final Map<AxisDirection,String> m = new HashMap<>(12);
+        m.put(AxisDirection.EAST,         AxisNames.EASTING);
+        m.put(AxisDirection.WEST,         AxisNames.WESTING);
+        m.put(AxisDirection.NORTH,        AxisNames.NORTHING);
+        m.put(AxisDirection.SOUTH,        AxisNames.SOUTHING);
+        m.put(AxisDirection.GEOCENTRIC_X, AxisNames.GEOCENTRIC_X);
+        m.put(AxisDirection.GEOCENTRIC_Y, AxisNames.GEOCENTRIC_Y);
+        m.put(AxisDirection.GEOCENTRIC_Z, AxisNames.GEOCENTRIC_Z);
+        CARTESIAN = m;
+    }
+
+    /**
      * A transliterator compliant with ISO 19162 on a <cite>"best effort"</cite> basis.
      * All methods perform the default implementation documented in this {@code Transliterator} class.
      */
@@ -224,9 +245,10 @@ public abstract class Transliterator imp
             }
             case WKTKeywords.Cartesian: {
                 if (name.length() <= 1) {
-                    if      (direction.equals(AxisDirection.GEOCENTRIC_X)) return AxisNames.GEOCENTRIC_X;
-                    else if (direction.equals(AxisDirection.GEOCENTRIC_Y)) return AxisNames.GEOCENTRIC_Y;
-                    else if (direction.equals(AxisDirection.GEOCENTRIC_Z)) return AxisNames.GEOCENTRIC_Z;
+                    final String c = CARTESIAN.get(direction);
+                    if (c != null) {
+                        return c;
+                    }
                 }
                 break;
             }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java?rev=1688429&r1=1688428&r2=1688429&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTParserTest.java [UTF-8] Tue Jun 30 11:25:44 2015
@@ -23,6 +23,7 @@ import org.opengis.test.wkt.CRSParserTes
 import org.apache.sis.internal.metadata.AxisNames;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
+import org.junit.Ignore;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
@@ -131,4 +132,40 @@ public class WKTParserTest extends CRSPa
         assertEquals(AxisNames.GEOCENTRIC_Y, cs.getAxis(1).getName().getCode());
         assertEquals(AxisNames.GEOCENTRIC_Z, cs.getAxis(2).getName().getCode());
     }
+
+    /**
+     * Ignored for now, because the Lambert Azimuthal Equal Area projection method is not yet implemented.
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    @Ignore("Lambert Azimuthal Equal Area projection method not yet implemented.")
+    public void testProjected() throws FactoryException {
+    }
+
+    /**
+     * Completes the GeoAPI tests with a check of axis names.
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    public void testProjectedWithFootUnits() throws FactoryException {
+        super.testProjectedWithFootUnits();
+        final CoordinateSystem cs = object.getCoordinateSystem();
+        assertEquals(AxisNames.EASTING,  cs.getAxis(0).getName().getCode());
+        assertEquals(AxisNames.NORTHING, cs.getAxis(1).getName().getCode());
+    }
+
+    /**
+     * Ignored for now, because the Transverse Mercator projection method is not yet implemented.
+     *
+     * @throws FactoryException if an error occurred during the WKT parsing.
+     */
+    @Test
+    @Override
+    @Ignore("Transverse Mercator projection method not yet implemented.")
+    public void testProjectedWithImplicitUnits() throws FactoryException {
+    }
 }

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=1688429&r1=1688428&r2=1688429&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 Jun 30 11:25:44 2015
@@ -257,6 +257,13 @@ public final class Units extends Static
             if (abs(factor - (PI / 200)) <= (EPS * PI/200)) {
                 return (Unit<A>) NonSI.GRADE;
             }
+        } else if (SI.METRE.equals(unit)) {
+            if (abs(factor - 0.3048) <= (EPS * 0.3048)) {
+                return (Unit<A>) NonSI.FOOT;
+            }
+            if (abs(factor - (1200.0/3937)) <= (EPS * (1200.0/3937))) {
+                return (Unit<A>) NonSI.FOOT_SURVEY_US;
+            }
         }
         if (abs(factor - 1) > EPS) {
             final long fl = (long) factor;