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/09 15:50:00 UTC
svn commit: r1684423 - in /sis/branches/JDK8/core:
sis-metadata/src/main/java/org/apache/sis/io/wkt/
sis-referencing/src/main/java/org/apache/sis/internal/referencing/
sis-referencing/src/main/java/org/apache/sis/parameter/
sis-referencing/src/main/jav...
Author: desruisseaux
Date: Tue Jun 9 13:49:59 2015
New Revision: 1684423
URL: http://svn.apache.org/r1684423
Log:
WKT: fixed the handling of units in PrimeMeridian, and added tests.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -1306,7 +1306,7 @@ public class Formatter implements Locali
/**
* Adds a unit to use for the next measurements of the quantity {@code Q}. The given unit will apply to
* all WKT elements containing a value of quantity {@code Q} without their own {@code UNIT[…]} element,
- * until the {@link #removeContextualUnit(Unit)} method is invoked with a unit of the same quantity.
+ * until the {@link #restoreContextualUnit(Unit, Unit)} method is invoked.
*
* <p>If the given unit is null, then this method does nothing and returns {@code null}.</p>
*
@@ -1328,11 +1328,55 @@ public class Formatter implements Locali
}
/**
+ * Restores the contextual unit to its previous state before the call to {@link #addContextualUnit(Unit)}.
+ * This method is used in the following pattern:
+ *
+ * {@preformat java
+ * final Unit<?> previous = formatter.addContextualUnit(unit);
+ * // ... format some WKT elements here.
+ * formatter.restoreContextualUnit(unit, previous);
+ * }
+ *
+ * @param unit The value given in argument to {@code addContextualUnit(unit)} (can be {@code null}).
+ * @param previous The value returned by {@code addContextualUnit(unit)} (can be {@code null}).
+ * @throws IllegalStateException if this method has not been invoked in the pattern documented above.
+ *
+ * @since 0.6
+ */
+ public void restoreContextualUnit(final Unit<?> unit, final Unit<?> previous) {
+ if (previous == null) {
+ if (unit != null && units.remove(unit.toSI()) != unit) {
+ /*
+ * The unit that we removed was not the expected one. Probably the user has invoked
+ * addContextualUnit(…) again without a matching call to restoreContextualUnit(…).
+ * However this check does not work in Convention.WKT1_COMMON_UNITS mode, since the
+ * map is always empty in that mode.
+ */
+ if (!convention.usesCommonUnits()) {
+ throw new IllegalStateException();
+ }
+ }
+ } else if (units.put(previous.toSI(), previous) != unit) {
+ /*
+ * The unit that we replaced was not the expected one. Probably the user has invoked
+ * addContextualUnit(…) again without a matching call to restoreContextualUnit(…).
+ * Note that this case should never happen in Convention.WKT1_COMMON_UNITS mode,
+ * since 'previous' should never be non-null in that mode (if the user followed
+ * the documented pattern).
+ */
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
* Removes the unit previously added by a call to {@code addContextualUnit(unit)}.
* If the given unit is null, then this method does nothing.
*
* @param unit The contextual unit to remove, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #restoreContextualUnit(Unit, Unit)}.
*/
+ @Deprecated
public void removeContextualUnit(final Unit<?> unit) {
if (unit != null) {
units.remove(unit.toSI());
@@ -1340,14 +1384,14 @@ public class Formatter implements Locali
}
/**
- * Returns the unit to use instead than the given one, or {@code null} if there is no replacement
- * for {@code unit}. This method searches for a unit specified by {@link #addContextualUnit(Unit)}
+ * Returns the unit to use instead than the given one, or {@code unit} if there is no replacement.
+ * This method searches for a unit specified by {@link #addContextualUnit(Unit)}
* which {@linkplain Unit#isCompatible(Unit) is compatible} with the given unit.
*
* @param <Q> The quantity of the unit.
* @param unit The unit to replace by the contextual unit, or {@code null}.
* @return A contextual unit compatible with the given unit, or {@code unit}
- * if no contextual unit has been found.
+ * (which may be null) if no contextual unit has been found.
*/
public <Q extends Quantity> Unit<Q> toContextualUnit(final Unit<Q> unit) {
if (unit != null) {
@@ -1357,7 +1401,7 @@ public class Formatter implements Locali
return candidate;
}
}
- return null;
+ return unit;
}
/**
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -19,7 +19,6 @@ package org.apache.sis.internal.referenc
import java.util.Collection;
import java.util.logging.Logger;
import javax.measure.unit.Unit;
-import javax.measure.unit.NonSI;
import javax.measure.quantity.Angle;
import org.opengis.annotation.UML;
import org.opengis.annotation.Specification;
@@ -112,12 +111,12 @@ public final class ReferencingUtilities
* The preference will be given to the longitude axis, if found.
*
* @param cs The coordinate system from which to get the angular unit, or {@code null}.
- * @return The angular unit, of {@link NonSI#DEGREE_ANGLE} if no angular unit was found.
+ * @return The angular unit, of {@code null} if no angular unit was found.
*
* @since 0.6
*/
public static Unit<Angle> getAngularUnit(final CoordinateSystem cs) {
- Unit<Angle> unit = NonSI.DEGREE_ANGLE;
+ Unit<Angle> unit = null;
if (cs != null) {
for (int i = cs.getDimension(); --i>=0;) {
final CoordinateSystemAxis axis = cs.getAxis(i);
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/AbstractParameterDescriptor.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -17,7 +17,6 @@
package org.apache.sis.parameter;
import java.util.Map;
-import javax.measure.unit.Unit;
import org.opengis.util.InternationalString;
import org.opengis.parameter.ParameterDirection;
import org.opengis.parameter.ParameterDescriptor;
@@ -344,12 +343,7 @@ public abstract class AbstractParameterD
if (defaultValue != null) {
formatter.appendAny(defaultValue);
}
- final Unit<?> unit = ((ParameterDescriptor<?>) this).getUnit();
- if (unit != null) {
- if (!formatter.getConvention().isSimplified() || !unit.equals(formatter.toContextualUnit(unit))) {
- formatter.append(unit);
- }
- }
+ formatter.append(((ParameterDescriptor<?>) this).getUnit());
}
return WKTKeywords.Parameter;
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -819,9 +819,51 @@ public class DefaultParameterValue<T> ex
* Parameter["False easting", 0.0, LengthUnit["metre", 1]]
* }
*
- * <div class="note"><b>Compatibility note:</b>
- * Version 1 of WKT format did not specified the parameter unit explicitely.
- * Instead, the unit was inherited from the enclosing element.</div>
+ * <div class="section">Unit of measurement</div>
+ * The units of measurement were never specified in WKT 1 format, and are optional in WKT 2 format.
+ * If the units are not specified, then they are inferred from the context.
+ * Typically, parameter values that are lengths are given in the unit for the projected CRS axes
+ * while parameter values that are angles are given in the unit for the base geographic CRS.
+ *
+ * <div class="note"><b>Example:</b>
+ * The table below shows WKT representations of the map projection parameters of a projected CRS
+ * (most other elements are omitted). The map projection uses a <cite>"Latitude of natural origin"</cite>
+ * parameters which is set to 52 <strong>grads</strong>, as defined in the {@code UNIT[…]} element of the
+ * enclosing CRS. A similar rule applies to <cite>“False easting”</cite> and <cite>“False northing”</cite>
+ * parameters, which are in kilometres in this example.
+ *
+ * <table class="sis">
+ * <caption>Parameters in a Projected CRS</caption>
+ * <tr>
+ * <td>WKT 1</td>
+ * <td>WKT 2</td>
+ * </tr><tr><td>
+ * {@preformat wkt
+ * PROJCS[…,
+ * GEOGCS[…,
+ * UNIT[“grad”, 0.015707963267948967]], // Unit for all angles
+ * PROJECTION[“Lambert_Conformal_Conic_1SP”]
+ * PARAMETER[“latitude_of_origin”, 52.0], // In grads
+ * PARAMETER[“scale_factor”, 0.99987742],
+ * PARAMETER[“false_easting”, 600.0], // In kilometres
+ * PARAMETER[“false_northing”, 2200.0], // In kilometres
+ * UNIT[“km”, 1000]] // Unit for all lengths
+ * }
+ * </td><td>
+ * {@preformat wkt
+ * ProjectedCRS[…
+ * BaseGeodCRS[…
+ * AngleUnit[“grad”, 0.015707963267948967]],
+ * Conversion["Lambert zone II",
+ * Method["Lambert Conic Conformal (1SP)"],
+ * Parameter["Latitude of natural origin", 52.0],
+ * Parameter["Scale factor at natural origin", 0.99987742],
+ * Parameter["False easting", 600.0],
+ * Parameter["False northing", 2200.0]],
+ * CS["Cartesian", 2],
+ * LengthUnit["km", 1000]]
+ * }
+ * </td></tr></table></div>
*
* @param formatter The formatter where to format the inner content of this WKT element.
* @return {@code "Parameter"} or {@code "ParameterFile"}.
@@ -841,7 +883,8 @@ public class DefaultParameterValue<T> ex
* Otherwise we can write the value as-is.
*/
final Unit<?> unit = getUnit(); // Gives to users a chance to override this property.
- if (isWKT1 && targetUnit != null) {
+ final boolean sameUnit = Objects.equals(unit, targetUnit);
+ if (isWKT1 && !sameUnit) {
double convertedValue;
try {
convertedValue = doubleValue(targetUnit);
@@ -868,10 +911,28 @@ public class DefaultParameterValue<T> ex
* The only exception is when the parameter unit is not the same than the contextual unit,
* in which case we have no choice: we must format that unit.
*/
- if (unit != null && !isWKT1 && (!convention.isSimplified() || !unit.equals(targetUnit))) {
+ if (!isWKT1 && (!sameUnit || !convention.isSimplified() || !hasContextualUnit(formatter))) {
formatter.append(unit);
// ID will be added by the Formatter itself.
}
return WKTKeywords.Parameter;
}
+
+ /**
+ * Returns {@code true} if the given formatter has contextual units, in which case the WKT format can omit
+ * the unit of measurement. The contextual units may be defined either in the direct parent or in the parent
+ * of the parent, depending if we are formatting WKT1 or WKT2 respectively. This is because WKT2 wraps the
+ * parameters in an additional {@code CONVERSION[…]} element which is not present in WKT1.
+ *
+ * <p>Taking the example documented in {@link #formatTo(Formatter)}:</p>
+ * <ul>
+ * <li>in WKT 1, {@code PROJCS[…]} is the immediate parent of {@code PARAMETER[…]}, but</li>
+ * <li>in WKT 2, {@code ProjectedCRS[…]} is the parent of {@code Conversion[…]},
+ * which is the parent of {@code Parameter[…]}.</li>
+ * </ul>
+ */
+ private static boolean hasContextualUnit(final Formatter formatter) {
+ return formatter.hasContextualUnit(1) || // In WKT1
+ formatter.hasContextualUnit(2); // In WKT2
+ }
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -524,8 +524,7 @@ public class AbstractCRS extends Abstrac
formatter.append(unit);
formatter.indent(-1);
}
- formatter.removeContextualUnit(unit);
- formatter.addContextualUnit(oldUnit);
+ formatter.restoreContextualUnit(unit, oldUnit);
formatter.newLine(); // For writing the ID[…] element on its own line.
}
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -17,7 +17,9 @@
package org.apache.sis.referencing.crs;
import java.util.Map;
+import javax.measure.unit.Unit;
import javax.measure.unit.NonSI;
+import javax.measure.quantity.Angle;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@@ -178,6 +180,7 @@ class DefaultGeodeticCRS extends Abstrac
WKTUtilities.appendName(this, formatter, null);
final Convention convention = formatter.getConvention();
final boolean isWKT1 = (convention.majorVersion() == 1);
+ CoordinateSystem cs = getCoordinateSystem();
/*
* Unconditionally format the datum element, followed by the prime meridian.
* The prime meridian is part of datum according ISO 19111, but is formatted
@@ -188,13 +191,16 @@ class DefaultGeodeticCRS extends Abstrac
formatter.append(toFormattable(datum));
formatter.newLine();
final PrimeMeridian pm = datum.getPrimeMeridian();
+ final Unit<Angle> angularUnit = ReferencingUtilities.getAngularUnit(cs);
if (convention != Convention.WKT2_SIMPLIFIED ||
ReferencingUtilities.getGreenwichLongitude(pm, NonSI.DEGREE_ANGLE) != 0)
{
+ final Unit<Angle> oldUnit = formatter.addContextualUnit(angularUnit);
formatter.indent(1);
formatter.append(toFormattable(pm));
formatter.indent(-1);
formatter.newLine();
+ formatter.restoreContextualUnit(angularUnit, oldUnit);
}
/*
* Get the coordinate system to format. This will also determine the units to write and the keyword to
@@ -205,7 +211,6 @@ class DefaultGeodeticCRS extends Abstrac
* NOT create an instance of a subclass (because the distinction between geographic and geocentric CRS
* is not anymore in ISO 19111:2007).
*/
- CoordinateSystem cs = getCoordinateSystem();
final boolean isBaseCRS;
if (isWKT1) {
if (!(cs instanceof EllipsoidalCS)) { // Tested first because this is the most common case.
@@ -228,12 +233,13 @@ class DefaultGeodeticCRS extends Abstrac
* Note that even if we do not format the CS, we may still write the units if we are formatting in "simplified"
* mode (as opposed to the more verbose mode). This looks like the opposite of what we would expect, but this is
* because formatting the unit here allow us to avoid repeating the unit in projection parameters when this CRS
- * is part of a ProjectedCRS.
+ * is part of a ProjectedCRS. Note however that in such case, the units to format are the angular units because
+ * the linear units will be formatted in the enclosing PROJCS[…] element.
*/
if (!isBaseCRS) {
formatCS(formatter, cs, isWKT1); // Will also format the axis unit.
} else if (convention.isSimplified()) {
- formatter.append(formatter.toContextualUnit(ReferencingUtilities.getAngularUnit(cs)));
+ formatter.append(formatter.toContextualUnit(angularUnit));
}
/*
* For WKT 1, the keyword depends on the subclass: "GeogCS" for GeographicCRS or "GeocCS" for GeocentricCRS.
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -44,7 +44,6 @@ import org.apache.sis.internal.referenci
import org.apache.sis.internal.util.Constants;
import org.apache.sis.io.wkt.FormattableObject;
import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.io.wkt.Convention;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.logging.Logging;
@@ -383,11 +382,10 @@ public class DefaultProjectedCRS extends
return super.formatTo(formatter);
}
WKTUtilities.appendName(this, formatter, null);
- final Convention convention = formatter.getConvention();
- final boolean isWKT1 = (convention.majorVersion() == 1);
- final GeographicCRS baseCRS = getBaseCRS();
- final Unit<Angle> unit = ReferencingUtilities.getAngularUnit(baseCRS.getCoordinateSystem());
- final Unit<Angle> oldUnit = formatter.addContextualUnit(unit);
+ final boolean isWKT1 = (formatter.getConvention().majorVersion() == 1);
+ final GeographicCRS baseCRS = getBaseCRS();
+ final Unit<Angle> unit = ReferencingUtilities.getAngularUnit(baseCRS.getCoordinateSystem());
+ final Unit<Angle> oldUnit = formatter.addContextualUnit(unit);
/*
* Format the enclosing base CRS. Note that WKT 1 formats a full GeographicCRS while WKT 2 formats only
* the datum with the prime meridian (no coordinate system) and uses a different keyword ("BaseGeodCRS"
@@ -413,8 +411,7 @@ public class DefaultProjectedCRS extends
if (!isBaseCRS) {
formatCS(formatter, getCoordinateSystem(), isWKT1);
}
- formatter.removeContextualUnit(unit);
- formatter.addContextualUnit(oldUnit);
+ formatter.restoreContextualUnit(unit, oldUnit);
return isWKT1 ? WKTKeywords.ProjCS : isBaseCRS ? WKTKeywords.BaseProjCRS : WKTKeywords.ProjectedCRS;
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -348,16 +348,24 @@ public class DefaultPrimeMeridian extend
super.formatTo(formatter);
final Convention convention = formatter.getConvention();
final boolean isWKT1 = convention.majorVersion() == 1;
- Unit<Angle> targetUnit = formatter.toContextualUnit(NonSI.DEGREE_ANGLE);
- if (targetUnit == null) {
- targetUnit = NonSI.DEGREE_ANGLE;
- }
+ final Unit<Angle> targetUnit = formatter.toContextualUnit(NonSI.DEGREE_ANGLE);
formatter.append(isWKT1 ? getGreenwichLongitude(targetUnit) : getGreenwichLongitude());
if (isWKT1) {
return WKTKeywords.PrimeM;
}
final Unit<Angle> angularUnit = getAngularUnit(); // Gives to users a chance to override properties.
- if (!convention.isSimplified() || !targetUnit.equals(angularUnit)) {
+ if (!convention.isSimplified() || !targetUnit.equals(angularUnit) || !targetUnit.equals(NonSI.DEGREE_ANGLE)) {
+ /*
+ * Note on the equals(NonSI.DEGREE_ANGLE) check:
+ *
+ * In theory, that last check is not necessary since it would be legal to format the value in the
+ * unit of the axes of the enclosing GeographicCRS. However the relationship between the CRS axes
+ * and the prime meridian is less obvious in WKT2 than it was in WKT1, because the WKT2's UNIT[…]
+ * element is far from the PRIMEM[…] element while it was just below it in WKT1. Furthermore, the
+ * PRIMEM[…] unit is one source of incompatibility between various WKT1 parsers (e.g. GDAL is not
+ * conform to OGC 01-009 and ISO 19162). So we are safer to unconditionally format any unit other
+ * than degrees here, even if we could legally omit them.
+ */
formatter.append(angularUnit);
}
return WKTKeywords.PrimeMeridian;
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -18,11 +18,12 @@ package org.apache.sis.io.wkt;
import java.text.ParseException;
import org.opengis.referencing.crs.VerticalCRS;
+import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
import org.junit.Test;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
/**
@@ -36,6 +37,18 @@ import static org.junit.Assert.*;
@DependsOn(GeodeticObjectParserTest.class)
public final strictfp class WKTFormatTest extends TestCase {
/**
+ * The instance to use for the test, or {@code null} if none.
+ */
+ private WKTFormat format;
+
+ /**
+ * An instance used by {@link #testConsistency()} for parsing the WKT.
+ * May be a different instance than {@link #format} if the two instances
+ * do not use the same {@link Convention}.
+ */
+ private WKTFormat parser;
+
+ /**
* Verifies the condition documented in {@link WKTFormat#SHORT_DATE_PATTERN} javadoc.
*/
@Test
@@ -53,7 +66,7 @@ public final strictfp class WKTFormatTes
*/
@Test
public void testParse() throws ParseException {
- final WKTFormat format = new WKTFormat(null, null);
+ format = new WKTFormat(null, null);
final VerticalCRS crs = (VerticalCRS) format.parseObject(
"VERT_CS[“Gravity-related height”,\n" +
" VERT_DATUM[“Mean Sea Level”, 2005],\n" +
@@ -63,4 +76,102 @@ public final strictfp class WKTFormatTes
GeodeticObjectParserTest.assertNameAndIdentifierEqual("Gravity-related height", 0, crs);
GeodeticObjectParserTest.assertNameAndIdentifierEqual("Mean Sea Level", 0, crs.getDatum());
}
+
+ /**
+ * Tests consistency between the parser and the formatter when using the WKT 1 format.
+ * This test parses a WKT, formats it then parses again. We should obtain the same result.
+ *
+ * @throws ParseException if a parsing failed.
+ */
+ @Test
+ public void testConsistencyOfWKT1() throws ParseException {
+ format = new WKTFormat(null, null);
+ format.setConvention(Convention.WKT1);
+ parser = format;
+ testConsistency();
+ }
+
+ /**
+ * Tests consistency between the parser and the formatter when using the WKT 1 format.
+ * This test parses a WKT, formats it then parses again. We should obtain the same result.
+ *
+ * @throws ParseException if a parsing failed.
+ */
+ @Test
+ @DependsOnMethod("testConsistencyOfWKT1")
+ public void testConsistencyOfWKT1_WithCommonUnits() throws ParseException {
+ format = new WKTFormat(null, null);
+ format.setConvention(Convention.WKT1_COMMON_UNITS);
+ parser = format;
+ testConsistency();
+ }
+
+ /**
+ * Implementation of {@link #testConsistencyOfWKT1()} and variants.
+ *
+ * @throws ParseException if a parsing failed.
+ */
+ private void testConsistency() throws ParseException {
+ testConsistency(
+ "GEOGCS[“Tokyo”,"
+ + "DATUM[“Tokyo”,"
+ + "SPHEROID[“Bessel 1841”,6377397.155,299.1528128,AUTHORITY[“EPSG”,“7004”]],"
+ + "TOWGS84[-148,507,685,0,0,0,0],AUTHORITY[“EPSG”,“6301”]],"
+ + "PRIMEM[“Greenwich”,0,AUTHORITY[“EPSG”,“8901”]],"
+ + "UNIT[“DMSH”,0.0174532925199433,AUTHORITY[“EPSG”,“9108”]],"
+ + "AXIS[“Lat”,NORTH],"
+ + "AXIS[“Long”,EAST],"
+ + "AUTHORITY[“EPSG”,“4301”]]");
+
+ testConsistency(
+ "GEOGCS[“NTF (Paris)”,"
+ + "DATUM[“Nouvelle_Triangulation_Francaise”,"
+ + "SPHEROID[“Clarke 1880 (IGN)”,6378249.2,293.466021293627,AUTHORITY[“EPSG”,“7011”]],"
+ + "TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY[“EPSG”,“6275”]],"
+ + "PRIMEM[“Paris”,2.5969213,AUTHORITY[“EPSG”,“8903”]],"
+ + "UNIT[“grad”,0.015707963267949,AUTHORITY[“EPSG”,“9105”]],"
+ + "AXIS[“Lat”,NORTH],"
+ + "AXIS[“Long”,EAST],"
+ + "AUTHORITY[“EPSG”,“4807”]]");
+
+ testConsistency(
+ "PROJCS[“NTF (Paris) / France I”,"
+ + "GEOGCS[“NTF (Paris)”,"
+ + "DATUM[“Nouvelle_Triangulation_Francaise”,"
+ + "SPHEROID[“Clarke 1880 (IGN)”,6378249.2,293.466021293627,AUTHORITY[“EPSG”,“7011”]],"
+ + "TOWGS84[-168,-60,320,0,0,0,0],"
+ + "AUTHORITY[“EPSG”,“6275”]],"
+ + "PRIMEM[“Paris”,2.5969213,AUTHORITY[“EPSG”,“8903”]],"
+ + "UNIT[“grad”,0.015707963267949,AUTHORITY[“EPSG”,“9105”]],"
+ + "AXIS[“Lat”,NORTH],"
+ + "AXIS[“Long”,EAST],"
+ + "AUTHORITY[“EPSG”,“4807”]],"
+ + "PROJECTION[“Lambert_Conformal_Conic_1SP”],"
+ + "PARAMETER[“latitude_of_origin”,49.5],"
+ + "PARAMETER[“central_meridian”,0],"
+ + "PARAMETER[“scale_factor”,0.999877341],"
+ + "PARAMETER[“false_easting”,600000],"
+ + "PARAMETER[“false_northing”,1200000],"
+ + "UNIT[“metre”,1,AUTHORITY[“EPSG”,“9001”]],"
+ + "AXIS[“X”,EAST],"
+ + "AXIS[“Y”,NORTH],"
+ + "AUTHORITY[“EPSG”,“27581”]]");
+
+ testConsistency(
+ "VERT_CS[“mean sea level depth”,"
+ + "VERT_DATUM[“Mean Sea Level”,2005,AUTHORITY[“EPSG”,“5100”]],"
+ + "UNIT[“kilometre”,1000],AXIS[“Z”,DOWN]]");
+ }
+
+ /**
+ * Implementation of {@link #testConsistency()} for a single WKT.
+ *
+ * @throws ParseException if the parsing failed.
+ */
+ private void testConsistency(final String wkt) throws ParseException {
+ final Object expected = parser.parseObject(wkt);
+ final String reformat = format.format(expected);
+ final Object reparsed = format.parseObject(reformat);
+ assertEqualsIgnoreMetadata(expected, reparsed);
+ }
}
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -228,6 +228,26 @@ public final strictfp class DefaultGeogr
}
/**
+ * Tests WKT 1 formatting on a CRS using a prime meridian other than Greenwich.
+ *
+ * <p>This CRS used in this test is equivalent to {@code EPSG:4807} except for axis order,
+ * since EPSG defines (<var>latitude</var>, <var>longitude</var>) in grades.</p>
+ */
+ @Test
+ @DependsOnMethod("testWKT2")
+ public void testWKT1_ForNonGreenwich() {
+ assertWktEquals(Convention.WKT1,
+ "GEOGCS[“NTF (Paris)”,\n" +
+ " DATUM[“Nouvelle Triangulation Francaise”,\n" + // Formatter should replace "ç" by "c".
+ " SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" +
+ " PRIMEM[“Paris”, 2.5969213],\n" +
+ " UNIT[“grade”, 0.015707963267948967],\n" +
+ " AXIS[“Longitude”, EAST],\n" +
+ " AXIS[“Latitude”, NORTH]]",
+ HardCodedCRS.NTF);
+ }
+
+ /**
* Tests WKT 1 formatting using {@link Convention#WKT1_COMMON_UNITS}. That convention ignores the unit of
* measurement in {@code PRIMEM} element, and rather unconditionally interpret the angle unit as degrees.
* This is a violation of OGC 01-009 and ISO 19162 standards, but is required for compatibility with GDAL.
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java?rev=1684423&r1=1684422&r2=1684423&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java [UTF-8] Tue Jun 9 13:49:59 2015
@@ -241,8 +241,8 @@ public final strictfp class DefaultProje
" Method[“Equidistant Cylindrical (Spherical)”],\n" +
" Parameter[“Latitude of 1st standard parallel”, 0.0],\n" +
" Parameter[“Longitude of natural origin”, 0.0],\n" +
- " Parameter[“False easting”, 1000.0, Unit[“metre”, 1]],\n" +
- " Parameter[“False northing”, 2000.0, Unit[“metre”, 1]]],\n" +
+ " Parameter[“False easting”, 1000.0],\n" +
+ " Parameter[“False northing”, 2000.0]],\n" +
" CS[“Cartesian”, 2],\n" +
" Axis[“Easting (E)”, east],\n" +
" Axis[“Northing (N)”, north],\n" +