sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1684124 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/main/java/org/apache/sis/referencing/cs/ sis-referencing/src/test/java/org/apache/sis/io/wkt/
Date Mon, 08 Jun 2015 08:57:27 GMT
Author: desruisseaux
Date: Mon Jun  8 08:57:26 2015
New Revision: 1684124

URL: http://svn.apache.org/r1684124
Log:
WKT parsing: Axes names "Longitude" and "Latitude" should be replaced by "Geodetic longitude"
and "Geodetic latitude".
This is the converse of the work done by DefaultCoordinateSystemAxis.formatTo(Formatter).
Added corresponding tests.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java

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=1684124&r1=1684123&r2=1684124&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] Mon Jun  8 08:57:26 2015
@@ -262,7 +262,7 @@ final class GeodeticObjectParser extends
         if (child instanceof Element) {
             keyword = ((Element) child).keyword;
             if (keyword != null) {
-                if (keyword.equalsIgnoreCase(WKTKeywords.Axis))        return parseAxis 
    (element, SI.METRE, true);
+                if (keyword.equalsIgnoreCase(WKTKeywords.Axis))        return parseAxis 
    (element, false, SI.METRE, true);
                 if (keyword.equalsIgnoreCase(WKTKeywords.PrimeM))      return parsePrimem
   (element, NonSI.DEGREE_ANGLE);
                 if (keyword.equalsIgnoreCase(WKTKeywords.ToWGS84))     return parseToWGS84
  (element);
                 if (keyword.equalsIgnoreCase(WKTKeywords.Spheroid))    return parseSpheroid
 (element);
@@ -387,15 +387,16 @@ final class GeodeticObjectParser extends
      * to make the parser more tolerant to non-100% compliant WKT. Note that AXIS is really
the only element without
      * such AUTHORITY clause and the EPSG database provides authority code for all axis.</div>
      *
-     * @param  parent The parent element.
-     * @param  unit The contextual unit, usually {@code SI.METRE} or {@code SI.RADIAN}.
-     * @param  mandatory {@code true} if the axis is mandatory, or {@code false} if it is
optional.
+     * @param  parent       The parent element.
+     * @param  isGeographic {@code true} if the parent element is a geodetic CRS having an
ellipsoidal coordinate system.
+     * @param  unit         The contextual unit, usually {@code SI.METRE} or {@code SI.RADIAN}.
+     * @param  mandatory    {@code true} if the axis is mandatory, or {@code false} if it
is optional.
      * @return The {@code "AXIS"} element as a {@link CoordinateSystemAxis} object, or {@code
null}
      *         if the axis was not required and there is no axis object.
      * @throws ParseException if the {@code "AXIS"} element can not be parsed.
      */
-    private CoordinateSystemAxis parseAxis(final Element parent, final Unit<?> unit,
final boolean mandatory)
-            throws ParseException
+    private CoordinateSystemAxis parseAxis(final Element parent, final boolean isGeographic,
+            final Unit<?> unit, final boolean mandatory) throws ParseException
     {
         final Element element;
         if (mandatory) {
@@ -407,6 +408,19 @@ final class GeodeticObjectParser extends
             }
         }
         String name = CharSequences.trimWhitespaces(element.pullString("name"));
+        if (isGeographic) {
+            /*
+             * The longitude and latitude axis names are explicitly fixed by ISO 19111 to
"Geodetic longitude"
+             * and "Geodetic latitude". But ISO 19162 §7.5.3(ii) said that the "Geodetic"
part in those names
+             * shall be omitted at WKT formatting time. SIS's DefaultCoordinateSystemAxis.formatTo(Formatter)
+             * method performs this removal, so we apply the reverse operation here.
+             */
+            if (name.equalsIgnoreCase("Latitude") || name.equalsIgnoreCase("lat")) {
+                name = "Geodetic latitude";
+            } else if (name.equalsIgnoreCase("Longitude") || name.equalsIgnoreCase("long")
|| name.equalsIgnoreCase("lon")) {
+                name = "Geodetic longitude";
+            }
+        }
         final Element orientation = element.pullVoidElement("orientation");
         final AxisDirection direction = Types.forCodeName(AxisDirection.class, orientation.keyword,
mandatory);
         /*
@@ -679,11 +693,11 @@ final class GeodeticObjectParser extends
         final String           name       = element.pullString("name");
         final EngineeringDatum datum      = parseLocalDatum(element);
         final Unit<Length>     linearUnit = parseUnit(element, SI.METRE);
-        CoordinateSystemAxis   axis       = parseAxis(element, linearUnit, true);
+        CoordinateSystemAxis   axis       = parseAxis(element, false, linearUnit, true);
         final List<CoordinateSystemAxis> list = new ArrayList<>();
         do {
             list.add(axis);
-            axis = parseAxis(element, linearUnit, false);
+            axis = parseAxis(element, false, linearUnit, false);
         } while (axis != null);
         final CoordinateSystem cs = referencing.createAbstractCS(list.toArray(new CoordinateSystemAxis[list.size()]));
         try {
@@ -714,11 +728,11 @@ final class GeodeticObjectParser extends
         final Unit<Length>  linearUnit = parseUnit  (element, SI.METRE);
         CartesianCS cs;
         CoordinateSystemAxis axis0, axis1 = null, axis2 = null;
-        axis0 = parseAxis(element, linearUnit, false);
+        axis0 = parseAxis(element, false, linearUnit, false);
         try {
             if (axis0 != null) {
-                axis1 = parseAxis(element, linearUnit, true);
-                axis2 = parseAxis(element, linearUnit, true);
+                axis1 = parseAxis(element, false, linearUnit, true);
+                axis2 = parseAxis(element, false, linearUnit, true);
             }
             final Map<String,?> properties = parseAuthorityAndClose(element, name);
             if (axis0 != null && !isAxisIgnored) {
@@ -750,7 +764,7 @@ final class GeodeticObjectParser extends
         final String         name       = element.pullString("name");
         final VerticalDatum  datum      = parseVertDatum(element);
         final Unit<Length>   linearUnit = parseUnit(element, SI.METRE);
-        CoordinateSystemAxis axis       = parseAxis(element, linearUnit, false);
+        CoordinateSystemAxis axis       = parseAxis(element, false, linearUnit, false);
         try {
             if (axis == null || isAxisIgnored) {
                 axis = createAxis("h", AxisDirection.UP, linearUnit);
@@ -774,7 +788,7 @@ final class GeodeticObjectParser extends
         final String         name     = element.pullString("name");
         final TemporalDatum  datum    = parseTimeDatum(element);
         final Unit<Duration> timeUnit = parseUnit(element, SI.SECOND);
-        CoordinateSystemAxis axis     = parseAxis(element, timeUnit, false);
+        CoordinateSystemAxis axis     = parseAxis(element, false, timeUnit, false);
         try {
             if (axis == null || isAxisIgnored) {
                 axis = createAxis("t", AxisDirection.UP, timeUnit);
@@ -811,11 +825,11 @@ final class GeodeticObjectParser extends
              */
             name = datum.getName();
         }
-        CoordinateSystemAxis axis0 = parseAxis(element, angularUnit, false);
+        CoordinateSystemAxis axis0 = parseAxis(element, true, angularUnit, false);
         CoordinateSystemAxis axis1 = null;
         try {
             if (axis0 != null) {
-                axis1 = parseAxis(element, angularUnit, true);
+                axis1 = parseAxis(element, true, angularUnit, true);
             }
             if (axis0 == null || isAxisIgnored) {
                 axis0 = createAxis("λ", AxisDirection.EAST,  angularUnit);
@@ -850,11 +864,11 @@ final class GeodeticObjectParser extends
         final Conversion    conversion = parseProjection(element, linearUnit,
                 (convention == Convention.WKT1_COMMON_UNITS) ? NonSI.DEGREE_ANGLE :
                 geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class));
-        CoordinateSystemAxis axis0 = parseAxis(element, linearUnit, false);
+        CoordinateSystemAxis axis0 = parseAxis(element, false, linearUnit, false);
         CoordinateSystemAxis axis1 = null;
         try {
             if (axis0 != null) {
-                axis1 = parseAxis(element, linearUnit, true);
+                axis1 = parseAxis(element, false, linearUnit, true);
             }
             if (axis0 == null || isAxisIgnored) {
                 axis0 = createAxis("x", AxisDirection.EAST,  linearUnit);

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1684124&r1=1684123&r2=1684124&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
[UTF-8] Mon Jun  8 08:57:26 2015
@@ -143,6 +143,9 @@ public class DefaultCoordinateSystemAxis
      * <p>Keys in this map are names <strong>in lower cases</strong>.
      * Values are any object that allow us to differentiate latitude from longitude.</p>
      *
+     * <p>Similar strings appear in {@link #formatTo(Formatter)} and
+     * {@code org.apache.sis.io.wkt.GeodeticObjectParser.parseAxis(…)}.</p>
+     *
      * @see #isHeuristicMatchForName(String)
      */
     private static final Map<String,Object> ALIASES = new HashMap<>(12);
@@ -802,6 +805,8 @@ public class DefaultCoordinateSystemAxis
                 } else if (name.equalsIgnoreCase("Geodetic longitude")) {
                     name = "Longitude";
                 }
+                // Note: the converse of this operation is done in
+                // org.apache.sis.io.wkt.GeodeticObjectParser.parseAxis(…).
             }
         }
         /*

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1684124&r1=1684123&r2=1684124&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
[UTF-8] Mon Jun  8 08:57:26 2015
@@ -27,6 +27,7 @@ import org.opengis.referencing.Identifie
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
 import org.opengis.referencing.datum.*;
+import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -47,6 +48,7 @@ import static org.apache.sis.test.Refere
     MathTransformParserTest.class,
     org.apache.sis.referencing.crs.DefaultGeocentricCRSTest.class,
     org.apache.sis.referencing.crs.DefaultGeographicCRSTest.class,
+    org.apache.sis.referencing.crs.DefaultProjectedCRSTest.class,
     org.apache.sis.referencing.crs.DefaultVerticalCRSTest.class,
     org.apache.sis.referencing.crs.DefaultTemporalCRSTest.class,
     org.apache.sis.referencing.crs.DefaultCompoundCRSTest.class,
@@ -89,17 +91,21 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Asserts the given axis is a longitude axis of the given name.
+     * Asserts that the given axis is a longitude axis. This method expects the name to be
+     * <cite>"Geodetic longitude"</cite> even if the WKT string contained a different
name,
+     * because {@link GeodeticObjectParser} should have done the replacement.
      */
-    private static void assertLongitudeAxisEquals(final String name, final CoordinateSystemAxis
axis) {
-        assertAxisEquals(name, "λ", AxisDirection.EAST, -180, +180, NonSI.DEGREE_ANGLE,
RangeMeaning.WRAPAROUND, axis);
+    private static void assertLongitudeAxisEquals(final CoordinateSystemAxis axis) {
+        assertAxisEquals("Geodetic longitude", "λ", AxisDirection.EAST, -180, +180, NonSI.DEGREE_ANGLE,
RangeMeaning.WRAPAROUND, axis);
     }
 
     /**
-     * Asserts the given axis is a latitude axis of the given name.
+     * Asserts that the given axis is a latitude axis. This method expects the name to be
+     * <cite>"Geodetic latitude"</cite> even if the WKT string contained a different
name,
+     * because {@link GeodeticObjectParser} should have done the replacement.
      */
-    private static void assertLatitudeAxisEquals(final String name, final CoordinateSystemAxis
axis) {
-        assertAxisEquals(name, "φ", AxisDirection.NORTH, -90, +90, NonSI.DEGREE_ANGLE, RangeMeaning.EXACT,
axis);
+    private static void assertLatitudeAxisEquals(final CoordinateSystemAxis axis) {
+        assertAxisEquals("Geodetic latitude", "φ", AxisDirection.NORTH, -90, +90, NonSI.DEGREE_ANGLE,
RangeMeaning.EXACT, axis);
     }
 
     /**
@@ -151,11 +157,123 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests the parsing of a geographic CRS from a WKT 1 string using (longitude, latitude)
axis order.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    public void testGeographicCRS() throws ParseException {
+        testGeographicCRS(0,
+               "  GEOGCS[“WGS84”,\n" +
+               "    DATUM[“World Geodetic System 1984”,\n" +
+               "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+               "      PRIMEM[“Greenwich”, 0.0],\n" +
+               "    UNIT[“degree”, 0.017453292519943295],\n" +
+               "    AXIS[“Longitude”, EAST],\n" +
+               "    AXIS[“Latitude”, NORTH]]");
+    }
+
+    /**
+     * Tests the parsing of a geographic CRS from a WKT 1 string using (latitude, longitude)
axis order.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testGeographicCRS")
+    public void testAxisSwapping() throws ParseException {
+        testGeographicCRS(1,
+               "  GEOGCS[“WGS84”,\n" +
+               "    DATUM[“World Geodetic System 1984”,\n" +
+               "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+               "      PRIMEM[“Greenwich”, 0.0],\n" +
+               "    UNIT[“degree”, 0.017453292519943295],\n" +
+               "    AXIS[“Latitude”, NORTH],\n" +
+               "    AXIS[“Longitude”, EAST]]");
+    }
+
+    /**
+     * Implementation of {@link #testGeographicCRS()} and {@link #testAxisSwapping()}.
+     *
+     * @param swap 1 if axes are expected to be swapped, or 0 otherwise.
+     */
+    private void testGeographicCRS(final int swap, final String wkt) throws ParseException
{
+        final GeographicCRS crs = parse(GeographicCRS.class, wkt);
+        assertNameAndIdentifierEqual("WGS84", 0, crs);
+
+        final GeodeticDatum datum = crs.getDatum();
+        assertNameAndIdentifierEqual("World Geodetic System 1984", 0, datum);
+        assertNameAndIdentifierEqual("Greenwich", 0, datum.getPrimeMeridian());
+
+        final Ellipsoid ellipsoid = datum.getEllipsoid();
+        assertNameAndIdentifierEqual("WGS84", 0, ellipsoid);
+        assertEquals("semiMajor", 6378137, ellipsoid.getSemiMajorAxis(), STRICT);
+        assertEquals("inverseFlattening", 298.257223563, ellipsoid.getInverseFlattening(),
STRICT);
+
+        final EllipsoidalCS cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 2, cs.getDimension());
+        assertLongitudeAxisEquals(cs.getAxis(0 ^ swap));
+        assertLatitudeAxisEquals (cs.getAxis(1 ^ swap));
+    }
+
+    /**
+     * Tests the parsing of a projected CRS from a WKT 1 string.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testGeographicCRS")
+    public void testProjectedCRS() throws ParseException {
+        final ProjectedCRS crs = parse(ProjectedCRS.class,
+                "PROJCS[“Mercator test”,\n" +
+               "  GEOGCS[“WGS84”,\n" +
+               "    DATUM[“World Geodetic System 1984”,\n" +
+               "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+               "      PRIMEM[“Greenwich”, 0.0],\n" +
+               "    UNIT[“degree”, 0.017453292519943295],\n" +
+               "    AXIS[“Longitude”, EAST],\n" +
+               "    AXIS[“Latitude”, NORTH]],\n" +
+               "  PROJECTION[“Mercator_1SP”],\n" +
+               "  PARAMETER[“central_meridian”, -20.0],\n" +
+               "  PARAMETER[“scale_factor”, 1.0],\n" +
+               "  PARAMETER[“false_easting”, 500000.0],\n" +
+               "  PARAMETER[“false_northing”, 0.0],\n" +
+               "  UNIT[“metre”, 1.0],\n" +
+               "  AXIS[“Easting”, EAST],\n" +
+               "  AXIS[“Northing”, NORTH]]");
+
+        assertNameAndIdentifierEqual("Mercator test", 0, crs);
+
+        final GeodeticDatum datum = crs.getDatum();
+        assertNameAndIdentifierEqual("World Geodetic System 1984", 0, datum);
+        assertNameAndIdentifierEqual("Greenwich", 0, datum.getPrimeMeridian());
+
+        final Ellipsoid ellipsoid = datum.getEllipsoid();
+        assertNameAndIdentifierEqual("WGS84", 0, ellipsoid);
+        assertEquals("semiMajor", 6378137, ellipsoid.getSemiMajorAxis(), STRICT);
+        assertEquals("inverseFlattening", 298.257223563, ellipsoid.getInverseFlattening(),
STRICT);
+
+        final CartesianCS cs = crs.getCoordinateSystem();
+        assertEquals("dimension", 2, cs.getDimension());
+        assertUnboundedAxisEquals("Easting",  "E", AxisDirection.EAST,  SI.METRE, cs.getAxis(0));
+        assertUnboundedAxisEquals("Northing", "N", AxisDirection.NORTH, SI.METRE, cs.getAxis(1));
+
+        assertEquals("Mercator (variant A)", crs.getConversionFromBase().getMethod().getName().getCode());
+        final ParameterValueGroup param = crs.getConversionFromBase().getParameterValues();
+//      assertEquals("semi_major",   6378137.0, param.parameter("semi_major"      ).doubleValue(),
STRICT);
+//      assertEquals("semi_minor",   6356752.3, param.parameter("semi_minor"      ).doubleValue(),
0.1);
+        assertEquals("central_meridian", -20.0, param.parameter("central_meridian").doubleValue(),
STRICT);
+        assertEquals("scale_factor",       1.0, param.parameter("scale_factor"    ).doubleValue(),
STRICT);
+        assertEquals("false_easting", 500000.0, param.parameter("false_easting"   ).doubleValue(),
STRICT);
+        assertEquals("false_northing",     0.0, param.parameter("false_northing"  ).doubleValue(),
STRICT);
+    }
+
+    /**
      * Tests the parsing of a compound CRS from a WKT 1 string, except the time dimension
which is WKT 2.
      *
      * @throws ParseException if the parsing failed.
      */
     @Test
+    @DependsOnMethod("testGeographicCRS")
     public void testCompoundCRS() throws ParseException {
         final CompoundCRS crs = parse(CompoundCRS.class,
                 "COMPD_CS[“WGS 84 + height + time”,\n" +
@@ -208,8 +326,8 @@ public final strictfp class GeodeticObje
         // Axes: we verify only the CompoundCRS ones, which should include all others.
         final CoordinateSystem cs = crs.getCoordinateSystem();
         assertEquals("dimension", 4, cs.getDimension());
-        assertLongitudeAxisEquals("Longitude", cs.getAxis(0));
-        assertLatitudeAxisEquals ("Latitude", cs.getAxis(1));
+        assertLongitudeAxisEquals(cs.getAxis(0));
+        assertLatitudeAxisEquals (cs.getAxis(1));
         assertUnboundedAxisEquals("Gravity-related height", "H", AxisDirection.UP, SI.METRE,
cs.getAxis(2));
         assertUnboundedAxisEquals("Time", "t", AxisDirection.FUTURE, NonSI.DAY, cs.getAxis(3));
     }



Mime
View raw message