Author: desruisseaux
Date: Tue Mar 29 15:02:20 2016
New Revision: 1737010
URL: http://svn.apache.org/viewvc?rev=1737010&view=rev
Log:
Add more tests. For easier debugging, provide a SIS-specific WKT format for
ConcatenatedOperation (this case does not seem to be described by WKT 2 format).
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1737010&r1=1737009&r2=1737010&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] Tue Mar 29 15:02:20 2016
@@ -32,6 +32,7 @@ import org.opengis.metadata.quality.Posi
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform;
@@ -857,32 +858,45 @@ check: for (int isTarget=0; ; isTar
protected String formatTo(final Formatter formatter) {
super.formatTo(formatter);
formatter.newLine();
- append(formatter, getSourceCRS(), WKTKeywords.SourceCRS);
- append(formatter, getTargetCRS(), WKTKeywords.TargetCRS);
- formatter.append(DefaultOperationMethod.castOrCopy(getMethod()));
- ParameterValueGroup parameters;
- try {
- parameters = getParameterValues();
- } catch (UnsupportedOperationException e) {
- final IdentifiedObject c = getParameterDescriptors();
- formatter.setInvalidWKT(c != null ? c : this, e);
- parameters = null;
+ /*
+ * If the WKT is a component of a ConcatenatedOperation, do not format
the source and target CRS.
+ * This decision SIS-specific since the WKT 2 specification does not
define concatenated operations.
+ * The choice of content to omit may change in any future version.
+ */
+ final boolean isComponent = (formatter.getEnclosingElement(1)
instanceof ConcatenatedOperation);
+ if (!isComponent) {
+ append(formatter, getSourceCRS(), WKTKeywords.SourceCRS);
+ append(formatter, getTargetCRS(), WKTKeywords.TargetCRS);
}
- if (parameters != null) {
- formatter.newLine();
- for (final GeneralParameterValue param : parameters.values()) {
- WKTUtilities.append(param, formatter);
+ final OperationMethod method = getMethod();
+ if (method != null) {
+ formatter.append(DefaultOperationMethod.castOrCopy(method));
+ ParameterValueGroup parameters;
+ try {
+ parameters = getParameterValues();
+ } catch (UnsupportedOperationException e) {
+ final IdentifiedObject c = getParameterDescriptors();
+ formatter.setInvalidWKT(c != null ? c : this, e);
+ parameters = null;
}
- }
- append(formatter, getInterpolationCRS(), WKTKeywords.InterpolationCRS);
- final double accuracy = getLinearAccuracy();
- if (accuracy > 0) {
- formatter.append(new FormattableObject() {
- @Override protected String formatTo(final Formatter formatter)
{
- formatter.append(accuracy);
- return WKTKeywords.OperationAccuracy;
+ if (parameters != null) {
+ formatter.newLine();
+ for (final GeneralParameterValue param : parameters.values()) {
+ WKTUtilities.append(param, formatter);
}
- });
+ }
+ }
+ if (!isComponent) {
+ append(formatter, getInterpolationCRS(),
WKTKeywords.InterpolationCRS);
+ final double accuracy = getLinearAccuracy();
+ if (accuracy > 0) {
+ formatter.append(new FormattableObject() {
+ @Override protected String formatTo(final Formatter
formatter) {
+ formatter.append(accuracy);
+ return WKTKeywords.OperationAccuracy;
+ }
+ });
+ }
}
if (formatter.getConvention().majorVersion() == 1) {
formatter.setInvalidWKT(this, null);
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java?rev=1737010&r1=1737009&r2=1737010&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
[UTF-8] Tue Mar 29 15:02:20 2016
@@ -783,11 +783,29 @@ public class CoordinateOperationInferenc
if (step2.getName() == AXIS_CHANGES && mt2.getSourceDimensions() ==
mt2.getTargetDimensions()) main = step1;
if (main instanceof SingleOperation) {
final MathTransform mt =
factorySIS.getMathTransformFactory().createConcatenatedTransform(mt1, mt2);
- return createFromMathTransform(new
HashMap<>(IdentifiedObjects.getProperties(main)),
+ main = createFromMathTransform(new
HashMap<>(IdentifiedObjects.getProperties(main)),
sourceCRS, targetCRS, mt, ((SingleOperation)
main).getMethod(),
(main instanceof Transformation) ? Transformation.class :
SingleOperation.class);
+ } else {
+ main = factory.createConcatenatedOperation(defaultName(sourceCRS,
targetCRS), step1, step2);
}
- return factory.createConcatenatedOperation(defaultName(sourceCRS,
targetCRS), step1, step2);
+ /*
+ * Sometime we get a concatenated operation made of an operation
followed by its inverse.
+ * We can identity those case when the associated MathTransform is the
identity transform.
+ * In such case, simplify by replacing the ConcatenatedTransform by a
SingleTransform.
+ */
+ if (main instanceof ConcatenatedOperation &&
main.getMathTransform().isIdentity()) {
+ Class<? extends CoordinateOperation> type = null;
+ for (final CoordinateOperation component :
((ConcatenatedOperation) main).getOperations()) {
+ if (component instanceof Transformation) {
+ type = Transformation.class;
+ break;
+ }
+ }
+ main = createFromMathTransform(new
HashMap<>(IdentifiedObjects.getProperties(main)),
+ main.getSourceCRS(), main.getTargetCRS(),
main.getMathTransform(), null, type);
+ }
+ return main;
}
/**
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java?rev=1737010&r1=1737009&r2=1737010&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
[UTF-8] Tue Mar 29 15:02:20 2016
@@ -46,6 +46,7 @@ import static org.apache.sis.util.Utilit
// Branch-dependent imports
import java.util.Objects;
+import org.apache.sis.io.wkt.Formatter;
/**
@@ -325,6 +326,23 @@ final class DefaultConcatenatedOperation
return super.computeHashCode() + 37 * Objects.hashCode(operations);
}
+ /**
+ * Formats this coordinate operation in pseudo-WKT. This is specific to
Apache SIS since
+ * there is no concatenated operation in the Well Known Text (WKT) version
2 format.
+ *
+ * @param formatter The formatter to use.
+ * @return {@code "ConcatenatedOperation"}.
+ */
+ @Override
+ protected String formatTo(final Formatter formatter) {
+ super.formatTo(formatter);
+ for (final CoordinateOperation component : operations) {
+ formatter.append(castOrCopy(component));
+ }
+ formatter.setInvalidWKT(this, null);
+ return "ConcatenatedOperation";
+ }
+
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java?rev=1737010&r1=1737009&r2=1737010&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] Tue Mar 29 15:02:20 2016
@@ -22,6 +22,7 @@ import org.opengis.parameter.ParameterVa
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.SingleOperation;
+import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.referencing.CommonCRS;
@@ -79,11 +80,41 @@ public final strictfp class CoordinateOp
/**
* Creates a new {@link DefaultCoordinateOperationFactory} to use for
testing purpose.
* The same factory will be used for all tests in this class.
+ *
+ * @throws ParseException if an error occurred while preparing the WKT
parser.
*/
@BeforeClass
- public static void createFactory() {
+ public static void createFactory() throws ParseException {
factory = new DefaultCoordinateOperationFactory();
parser = new WKTFormat(null, null);
+ /*
+ * The fist keyword in WKT below should be "GeodeticCRS" in WKT 2, but
we use the WKT 1 keyword ("GEOGCS")
+ * for allowing inclusion in ProjectedCRS. SIS is okay with mixed WKT
versions, but this is of course not
+ * something to recommend in production.
+ */
+ parser.addFragment("Sphere",
+ "GEOGCS[“Sphere”,\n" +
+ " Datum[“Sphere”, Ellipsoid[“Sphere”, 6370997, 0]],\n" +
+ " CS[ellipsoidal, 2],\n" +
+ " Axis[“Longitude (λ)”, EAST],\n" +
+ " Axis[“Latitude (φ)”, NORTH],\n" +
+ " Unit[“degree”, 0.017453292519943295]]");
+ /*
+ * NAD27 (EPSG:4267), defined in WKT instead than relying on the
CommonCRS.NAD27 constant in order to fix
+ * the TOWGS84[…] parameter to values that we control. Note that
TOWGS84[…] is not a legal WKT 2 element.
+ * We could mix WKT 1 and WKT 2 elements (SIS allows that), but we
nevertheless use WKT 1 for the whole
+ * string as a matter of principle.
+ */
+ parser.addFragment("NAD27",
+ "GEOGCS[“Sphere”,\n" +
+ " DATUM[“North American Datum 1927”,\n" +
+ " SPHEROID[“Clarke 1866”, 6378206.4, 294.9786982138982],\n"
+
+ " TOWGS84[-10, 158, 187]]," +
+ " PRIMEM[“Greenwich”, 0.0]," +
+ " UNIT[“degree”, 0.017453292519943295],\n" +
+ " AXIS[“Latitude (φ)”, NORTH],\n" +
+ " AXIS[“Longitude (λ)”, EAST],\n" +
+ " AUTHORITY[“EPSG”, “4267”]]");
}
/**
@@ -125,36 +156,52 @@ public final strictfp class CoordinateOp
assertSame("sourceCRS", crs, operation.getSourceCRS());
assertSame("targetCRS", crs, operation.getTargetCRS());
assertTrue("isIdentity", operation.getMathTransform().isIdentity());
+ assertInstanceOf("operation", Conversion.class, operation);
+ }
+
+ /**
+ * Tests a transformation that requires a datum shift.
+ *
+ * @throws ParseException if a CRS used in this test can not be parsed.
+ * @throws FactoryException if the operation can not be created.
+ * @throws TransformException if an error occurred while converting the
test points.
+ */
+ @Test
+ @DependsOnMethod("testIdentityTransform")
+ public void testDatumShift() throws ParseException, FactoryException,
TransformException {
+ final CoordinateReferenceSystem sourceCRS = parse("$NAD27");
+ final CoordinateReferenceSystem targetCRS =
CommonCRS.WGS84.geographic();
+ final CoordinateOperation operation =
factory.createOperation(sourceCRS, targetCRS);
+ assertSame(sourceCRS, operation.getSourceCRS());
+ assertSame(targetCRS, operation.getTargetCRS());
+ transform = operation.getMathTransform();
+ tolerance = ANGULAR_TOLERANCE;
+ λDimension = new int[] {1};
+ verifyTransform(new double[] {
+ 39, -85,
+ 38.26, -80.58
+ }, new double[] {
+ 39.00011150, -84.99995603,
+ 38.26011883, -80.57981725
+ });
+ validate();
}
/**
* Tests conversion from a geographic to a projected CRS without datum of
axis changes.
*
- * @throws ParseException if the CRS used in this test can not be parsed.
+ * @throws ParseException if a CRS used in this test can not be parsed.
* @throws FactoryException if the operation can not be created.
* @throws TransformException if an error occurred while converting the
test points.
*/
@Test
@DependsOnMethod("testIdentityTransform")
public void testGeographicToProjected() throws ParseException,
FactoryException, TransformException {
- /*
- * The fist keyword in WKT below should be "GeodeticCRS" in WKT 2, but
we use the WKT 1 keyword ("GEOGCS")
- * for allowing inclusion in ProjectedCRS. SIS is okay with mixed WKT
versions, but this is of course not
- * something to recommend in production.
- */
- parser.addFragment("Sphere",
- "GEOGCS[“Sphere”,\n" +
- " Datum[“Sphere”, Ellipsoid[“Sphere”, 6370997, 0]],\n" +
- " CS[ellipsoidal, 2],\n" +
- " Axis[“Longitude (λ)”, EAST],\n" +
- " Axis[“Latitude (φ)”, NORTH],\n" +
- " Unit[“degree”, 0.017453292519943295]]");
-
final CoordinateReferenceSystem sourceCRS = parse("$Sphere");
final CoordinateReferenceSystem targetCRS = parse(
- "ProjectedCRS[“UTM”,\n" +
+ "ProjectedCRS[“TM”,\n" +
" $Sphere,\n" +
- " Conversion[“UTM”,\n" +
+ " Conversion[“TM”,\n" +
" Method[“Transverse Mercator”],\n" +
" Parameter[“Longitude of natural origin”, 170],\n" +
" Parameter[“Latitude of natural origin”, 50],\n" +
@@ -183,8 +230,9 @@ public final strictfp class CoordinateOp
verifyTransform(new double[] {170, 50}, new double[] {0, 0});
validate();
- transform = transform.inverse();
- tolerance = LINEAR_TOLERANCE;
+ transform = transform.inverse();
+ tolerance = LINEAR_TOLERANCE;
+ λDimension = new int[] {0};
verifyTransform(new double[] {0, 0}, new double[] {170, 50});
validate();
}