Author: desruisseaux
Date: Wed Apr 13 12:49:22 2016
New Revision: 1738930
URL: http://svn.apache.org/viewvc?rev=1738930&view=rev
Log:
Add test for DefaultCoordinateOperationFactory.
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
(with props)
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
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/DefaultConcatenatedOperation.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -67,7 +67,7 @@ public final class PositionalAccuracyCon
*
* @see
org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy()
*/
- private static final double UNKNOWN_ACCURACY = 3000;
+ public static final double UNKNOWN_ACCURACY = 3000;
/**
* Default accuracy of datum shift, if not explicitly provided in the EPSG
database.
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=1738930&r1=1738929&r2=1738930&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] Wed Apr 13 12:49:22 2016
@@ -160,7 +160,7 @@ public class AbstractCoordinateOperation
* (i.e., instantiation due to the stochastic nature of the parameters).
*
* <p><b>Consider this field as final!</b>
- * This field is modified only at unmarshalling time by {@link
#setOperationVersion(String)}</p>
+ * This field is modified only at unmarshalling time by {@link
#setOperationVersion(String)}.</p>
*
* @see #getOperationVersion()
*/
@@ -181,7 +181,7 @@ public class AbstractCoordinateOperation
* Area in which this operation is valid, or {@code null} if not available.
*
* <p><b>Consider this field as final!</b>
- * This field is modified only at unmarshalling time by {@link
#setDomainOfValidity(Extent)}</p>
+ * This field is modified only at unmarshalling time by {@link
#setDomainOfValidity(Extent)}.</p>
*
* @see #getDomainOfValidity()
*/
@@ -191,7 +191,7 @@ public class AbstractCoordinateOperation
* Description of domain of usage, or limitations of usage, for which this
operation is valid.
*
* <p><b>Consider this field as final!</b>
- * This field is modified only at unmarshalling time by {@link
#setScope(InternationalString)}</p>
+ * This field is modified only at unmarshalling time by {@link
#setScope(InternationalString)}.</p>
*
* @see #getScope()
*/
@@ -203,7 +203,7 @@ public class AbstractCoordinateOperation
*
* <p><b>Consider this field as final!</b>
* This field is non-final only for the convenience of constructors and
for initialization
- * at XML unmarshalling time by {@link
AbstractSingleOperation#afterUnmarshal(Unmarshaller, Object)}</p>
+ * at XML unmarshalling time by {@link
AbstractSingleOperation#afterUnmarshal(Unmarshaller, Object)}.</p>
*/
MathTransform transform;
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=1738930&r1=1738929&r2=1738930&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] Wed Apr 13 12:49:22 2016
@@ -17,17 +17,13 @@
package org.apache.sis.referencing.operation;
import java.util.Map;
-import java.util.Set;
import java.util.List;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashSet;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.opengis.util.FactoryException;
-import org.opengis.metadata.quality.PositionalAccuracy;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.ConcatenatedOperation;
@@ -37,8 +33,6 @@ import org.opengis.referencing.operation
import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.internal.util.CollectionsExt;
-import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
@@ -115,9 +109,8 @@ final class DefaultConcatenatedOperation
{
super(properties);
ArgumentChecks.ensureNonNull("operations", operations);
- final boolean setAccuracy = (coordinateOperationAccuracy == null);
final List<CoordinateOperation> flattened = new
ArrayList<>(operations.length);
- initialize(properties, operations, flattened, mtFactory, setAccuracy);
+ initialize(properties, operations, flattened, mtFactory,
(coordinateOperationAccuracy == null));
if (flattened.size() < 2) {
throw new
IllegalArgumentException(Errors.getResources(properties).getString(
Errors.Keys.TooFewOccurrences_2, 2,
CoordinateOperation.class));
@@ -126,10 +119,6 @@ final class DefaultConcatenatedOperation
this.operations = UnmodifiableArrayList.wrap(operations);
this.sourceCRS = operations[0].getSourceCRS();
this.targetCRS = operations[operations.length - 1].getTargetCRS();
- if (setAccuracy) {
- coordinateOperationAccuracy = CollectionsExt.unmodifiableOrCopy(
- (Set<PositionalAccuracy>) coordinateOperationAccuracy);
- }
checkDimensions(properties);
}
@@ -148,11 +137,11 @@ final class DefaultConcatenatedOperation
* in the given list. This should not happen according ISO 19111 standard,
but we try to be safe.
*
* <div class="section">How coordinate operation accuracy is
determined</div>
- * If {@code setAccuracy} is {@code true}, then this method collects all
accuracy information found in the
- * {@link Transformation} instances. This method ignores instances of
other kinds for the following reason:
+ * If {@code setAccuracy} is {@code true}, then this method copies
accuracy information found in the single
+ * {@link Transformation} instance. This method ignores instances of other
kinds for the following reason:
* some {@link Conversion} instances declare an accuracy, which is
typically close to zero. If a concatenated
* operation contains such conversion together with a transformation with
unknown accuracy, then we do not want
- * to declare that a 0 meter error as the concatenated operation accuracy;
it would be a false information.
+ * to declare "0 meter" as the concatenated operation accuracy; it would
be a false information.
* An other reason is that a concatenated operation typically contains an
arbitrary amount of conversions,
* but only one transformation. So considering only transformations
usually means to pickup only one operation
* in the given {@code operations} list, which make things clearer.
@@ -175,10 +164,9 @@ final class DefaultConcatenatedOperation
final CoordinateOperation[] operations,
final List<CoordinateOperation> flattened,
final MathTransformFactory mtFactory,
- final boolean setAccuracy)
+ boolean setAccuracy)
throws FactoryException
{
- double coarsestAccuracy = 0;
CoordinateReferenceSystem previous = null;
for (int i=0; i<operations.length; i++) {
final CoordinateOperation op = operations[i];
@@ -220,22 +208,22 @@ final class DefaultConcatenatedOperation
transform = (transform != null) ?
mtFactory.createConcatenatedTransform(transform, step) : step;
}
/*
- * Optionally update the coordinate operation accuracy.
- * See javadoc for a rational about why we take only
transformations in account.
+ * Optionally copy the coordinate operation accuracy from the
transformation (or from a concatenated
+ * operation on the assumption that its accuracy was computed by
the same algorithm than this method).
+ * See javadoc for a rational about why we take only
transformations in account. If more than one
+ * transformation is found, clear the collection and abandon the
attempt to set the accuracy information.
+ * Instead the user will get a better result by invoking
PositionalAccuracyConstant.getLinearAccuracy(…)
+ * since that method conservatively computes the sum of all linear
accuracy.
*/
- if (setAccuracy && op instanceof Transformation) {
- final Collection<PositionalAccuracy> candidates =
op.getCoordinateOperationAccuracy();
- if (!Containers.isNullOrEmpty(candidates)) {
- final double accuracy =
PositionalAccuracyConstant.getLinearAccuracy(op);
- if (accuracy > coarsestAccuracy) {
- coarsestAccuracy = accuracy;
- if (coordinateOperationAccuracy == null) {
- coordinateOperationAccuracy = new
LinkedHashSet<>(candidates);
- } else {
- coordinateOperationAccuracy.clear();
- coordinateOperationAccuracy.addAll(candidates);
- }
+ if (setAccuracy && (op instanceof Transformation || op instanceof
ConcatenatedOperation)) {
+ if (coordinateOperationAccuracy == null) {
+ setAccuracy =
(PositionalAccuracyConstant.getLinearAccuracy(op) > 0);
+ if (setAccuracy) {
+ coordinateOperationAccuracy =
op.getCoordinateOperationAccuracy();
}
+ } else {
+ coordinateOperationAccuracy = null;
+ setAccuracy = false;
}
}
}
@@ -391,8 +379,7 @@ final class DefaultConcatenatedOperation
*/
private void setSteps(final CoordinateOperation[] steps) throws
FactoryException {
final List<CoordinateOperation> flattened = new
ArrayList<>(steps.length);
- initialize(null, steps, flattened,
DefaultFactories.forBuildin(MathTransformFactory.class), true);
+ initialize(null, steps, flattened,
DefaultFactories.forBuildin(MathTransformFactory.class),
coordinateOperationAccuracy == null);
operations = UnmodifiableArrayList.wrap(flattened.toArray(new
CoordinateOperation[flattened.size()]));
- coordinateOperationAccuracy =
CollectionsExt.unmodifiableOrCopy((Set<PositionalAccuracy>)
coordinateOperationAccuracy);
}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -82,6 +82,12 @@ import org.apache.sis.util.Utilities;
*/
public class DefaultCoordinateOperationFactory extends AbstractFactory
implements CoordinateOperationFactory {
/**
+ * Whether this class is allowed to use the EPSG authority factory for
searching coordinate operation paths.
+ * This flag should always be {@code true}, except temporarily for testing
purposes.
+ */
+ static final boolean USE_EPSG_FACTORY = true;
+
+ /**
* The default properties, or an empty map if none. This map shall not
change after construction in
* order to allow usage without synchronization in multi-thread context.
But we do not need to wrap
* in a unmodifiable map since {@code DefaultCoordinateOperationFactory}
does not provide public
@@ -667,10 +673,10 @@ next: for (int i=components.size(); --
* validity} and the {@linkplain
CoordinateOperationContext#getAreaOfInterest() area of interest} is returned.
*
* <p>The default implementation is equivalent to the following code
- * (omitting the cast safety check for brevity):</p>
+ * (omitting the {@code registry} type check and cast for brevity):</p>
*
* {@preformat java
- * CoordinateOperationAuthorityFactory registry =
(CoordinateOperationAuthorityFactory) CRS.getAuthorityFactory("EPSG");
+ * CoordinateOperationAuthorityFactory registry =
CRS.getAuthorityFactory("EPSG"); // Actually needs cast
* return new CoordinateOperationFinder(registry, this,
context).createOperation(sourceCRS, targetCRS);
* }
*
@@ -693,7 +699,7 @@ next: for (int i=components.size(); --
final
CoordinateOperationContext context)
throws OperationNotFoundException, FactoryException
{
- final AuthorityFactory registry =
CRS.getAuthorityFactory(Constants.EPSG);
+ final AuthorityFactory registry = USE_EPSG_FACTORY ?
CRS.getAuthorityFactory(Constants.EPSG) : null;
return new CoordinateOperationFinder((registry instanceof
CoordinateOperationAuthorityFactory) ?
(CoordinateOperationAuthorityFactory) registry : null, this,
context).createOperation(sourceCRS, targetCRS);
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -91,7 +91,7 @@ final class InverseOperationMethod exten
}
if (!useSameParameters) {
Identifier name = method.getName();
- name = new ImmutableIdentifier(null, name.getCodeSpace(),
"Inverse " + name.getCode());
+ name = new ImmutableIdentifier(null, null, "Inverse of " +
name.getCode());
final Map<String,Object> properties = new HashMap<>(6);
properties.put(NAME_KEY, name);
properties.put(FORMULA_KEY, method.getFormula());
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -313,7 +313,7 @@ public final strictfp class CoordinateOp
* @param domain either {@code "geog2D domain"} or either {@code "geog3D
domain"}.
* @param isEPSG {@code true} if the coordinate operation is expected to
contain EPSG identifiers.
*/
- static void verifyNTF(final CoordinateOperation operation, final String
domain, final boolean isEPSG) {
+ private static void verifyNTF(final CoordinateOperation operation, final
String domain, final boolean isEPSG) {
assertInstanceOf("Operation should have two steps.",
ConcatenatedOperation.class, operation);
final List<? extends CoordinateOperation> steps =
((ConcatenatedOperation) operation).getOperations();
assertEquals("Operation should have two steps.", 2, steps.size());
@@ -342,9 +342,7 @@ public final strictfp class CoordinateOp
assertEquals("X-axis translation", -168, p2.parameter("X-axis
translation").doubleValue(), STRICT);
assertEquals("Y-axis translation", -60, p2.parameter("Y-axis
translation").doubleValue(), STRICT);
assertEquals("Z-axis translation", 320, p2.parameter("Z-axis
translation").doubleValue(), STRICT);
-
- assertEquals("Should report only the coarsest accuracy.", 1,
operation.getCoordinateOperationAccuracy().size());
- assertEquals("linearAccuracy", 2,
CRS.getLinearAccuracy(operation), STRICT);
+ assertEquals("linearAccuracy", 2,
CRS.getLinearAccuracy(operation), STRICT);
}
/**
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java?rev=1738930&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation;
+
+import java.util.List;
+import java.text.ParseException;
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+import org.opengis.referencing.operation.SingleOperation;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.io.wkt.WKTFormat;
+import org.apache.sis.referencing.CRS;
+
+// Test dependencies
+import org.apache.sis.referencing.operation.transform.MathTransformTestCase;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import static org.apache.sis.test.ReferencingAssert.*;
+
+
+/**
+ * Tests {@link DefaultCoordinateOperationFactory}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn({
+ CoordinateOperationRegistryTest.class,
+ CoordinateOperationFinderTest.class
+})
+public final strictfp class DefaultCoordinateOperationFactoryTest extends
MathTransformTestCase {
+ /**
+ * Tolerance threshold for strict comparisons of floating point numbers.
+ * This constant can be used like below, where {@code expected} and {@code
actual} are {@code double} values:
+ *
+ * {@preformat java
+ * assertEquals(expected, actual, STRICT);
+ * }
+ */
+ private static final double STRICT = 0;
+
+ /**
+ * The transformation factory to use for testing.
+ */
+ private static DefaultCoordinateOperationFactory factory;
+
+ /**
+ * The parser to use for WKT strings used in this test.
+ */
+ private static WKTFormat parser;
+
+ /**
+ * 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() throws ParseException {
+ factory = new DefaultCoordinateOperationFactory();
+ parser = new WKTFormat(null, null);
+ parser.addFragment("NTF",
+ "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
+ " BaseGeodCRS[“NTF (Paris)”,\n" +
+ " Datum[“Nouvelle Triangulation Française (Paris)”,\n" +
+ " Ellipsoid[“Clarke 1880 (IGN)”, 6378249.2,
293.4660212936269]],\n" +
+ " PrimeMeridian[“Paris”, 2.5969213],\n" +
+ " Unit[“grade”, 0.015707963267948967]]\n," +
+ " Conversion[“Lambert zone II”,\n" +
+ " Method[“Lambert Conic Conformal (1SP)”],\n" +
+ " Parameter[“Latitude of natural origin”, 52.0],\n" +
+ " Parameter[“Scale factor at natural origin”,
0.99987742],\n" +
+ " Parameter[“False easting”, 600000.0],\n" +
+ " Parameter[“False northing”, 2200000.0]],\n" +
+ " CS[Cartesian, 2]\n," +
+ " Axis[“Easting (X)”, east],\n" +
+ " Axis[“Northing (Y)”, north],\n" +
+ " Unit[“metre”, 1],\n" +
+ " Id[“EPSG”, 27572]]");
+
+ parser.addFragment("Mercator",
+ "ProjectedCRS[“WGS 84 / World Mercator”,\n" +
+ " BaseGeodCRS[“WGS 84”,\n" +
+ " Datum[“World Geodetic System 1984”,\n" +
+ " Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]],\n" +
+ " Unit[“degree”, 0.017453292519943295]],\n" +
+ " Conversion[“World Mercator”,\n" +
+ " Method[“Mercator (variant A)”]],\n" +
+ " CS[Cartesian, 2]\n," +
+ " Axis[“Easting (X)”, east],\n" +
+ " Axis[“Northing (Y)”, north],\n" +
+ " Unit[“metre”, 1],\n" +
+ " Id[“EPSG”, 3395]]");
+ }
+
+ /**
+ * Disposes the factory created by {@link #createFactory()} after all
tests have been executed.
+ */
+ @AfterClass
+ public static void disposeFactory() {
+ factory = null;
+ parser = null;
+ }
+
+ /**
+ * Returns the CRS for the given Well Known Text.
+ */
+ private static CoordinateReferenceSystem parse(final String wkt) throws
ParseException {
+ return (CoordinateReferenceSystem) parser.parseObject(wkt);
+ }
+
+ /**
+ * Returns {@code true} if {@link #factory} is expected to use the EPSG
factory.
+ */
+ private static boolean isUsingEpsgFactory() throws FactoryException {
+ return DefaultCoordinateOperationFactory.USE_EPSG_FACTORY &&
+ CRS.getAuthorityFactory(Constants.EPSG) instanceof
CoordinateOperationAuthorityFactory;
+ }
+
+ /**
+ * Tests a transformation between 2D projected CRS which implies a change
of prime meridian.
+ *
+ * @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
+ public void testProjectionAndLongitudeRotation() throws ParseException,
FactoryException, TransformException {
+ final CoordinateReferenceSystem sourceCRS = parse("$NTF");
+ final CoordinateReferenceSystem targetCRS = parse("$Mercator");
+ final CoordinateOperation operation =
factory.createOperation(sourceCRS, targetCRS);
+ assertSame ("sourceCRS", sourceCRS, operation.getSourceCRS());
+ assertSame ("targetCRS", targetCRS, operation.getTargetCRS());
+ assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+ /*
+ * The accuracy of the coordinate operation depends on whether a path
as been found with the help
+ * of the EPSG database (in which case the reported accuracy is 2
metres) or if we had to find an
+ * operation by ourselves (in which case we conservatively report an
accuracy of 3000 metres, bu
+ * in practice observe an error of about 80 metres for this test).
+ */
+ final boolean isUsingEpsgFactory =
verifyParametersNTF(((ConcatenatedOperation) operation).getOperations(), 1);
+ assertEquals("linearAccuracy", isUsingEpsgFactory ? 2 :
PositionalAccuracyConstant.UNKNOWN_ACCURACY,
+ CRS.getLinearAccuracy(operation),
STRICT);
+
+ tolerance = isUsingEpsgFactory ? Formulas.LINEAR_TOLERANCE : 100;
+ transform = operation.getMathTransform();
+ /*
+ * Test using the location of Paris (48.856578°N, 2.351828°E) first,
+ * then using a coordinate different than the prime meridian.
+ */
+ verifyTransform(new double[] {
+ 601124.99, 2428693.45,
+ 600000.00, 2420000.00
+ }, new double[] {
+ 261804.30, 6218365.73,
+ 260098.74, 6205194.95
+ });
+ validate();
+ }
+
+ /**
+ * Tests a transformation from a 4D projection to a 2D projection which
imply a change of
+ * prime meridian. This is the same test than {@link
#testProjectionAndLongitudeRotation()},
+ * with extra dimension which should be just dropped.
+ *
+ * <p>This tests requires the EPSG database, because it requires the
coordinate operation
+ * path which is defined there.</p>
+ *
+ * @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("testProjectionAndLongitudeRotation")
+ public void testCompoundAndLongitudeRotation() throws ParseException,
FactoryException, TransformException {
+ final CoordinateReferenceSystem sourceCRS = parse(
+ "CompoundCRS[“NTF 4D”," +
+ " $NTF,\n" +
+ " VerticalCRS[“Ellipsoidal height”,\n" +
+ " VerticalDatum[“Ellipsoid”],\n" +
+ " CS[vertical, 1],\n" +
+ " Axis[“Ellipsoidal height (h)”, up],\n" +
+ " Unit[“metre”, 1]],\n" +
+ " TimeCRS[“Modified Julian”,\n" +
+ " TimeDatum[“Modified Julian”,
TimeOrigin[1858-11-17T00:00:00.0Z]],\n" +
+ " CS[temporal, 1],\n" +
+ " Axis[“Time (t)”, future],\n" +
+ " TimeUnit[“day”, 86400]]]");
+
+ final CoordinateReferenceSystem targetCRS = parse("$Mercator");
+ final CoordinateOperation operation =
factory.createOperation(sourceCRS, targetCRS);
+ assertSame ("sourceCRS", sourceCRS, operation.getSourceCRS());
+ assertSame ("targetCRS", targetCRS, operation.getTargetCRS());
+ assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+ /*
+ * The accuracy of the coordinate operation depends on whether a path
as been found with the help
+ * of the EPSG database. See testProjectionAndLongitudeRotation() for
more information.
+ */
+ final boolean isUsingEpsgFactory =
verifyParametersNTF(((ConcatenatedOperation) operation).getOperations(), 2);
+ assertEquals("linearAccuracy", isUsingEpsgFactory ? 2 :
PositionalAccuracyConstant.UNKNOWN_ACCURACY,
+ CRS.getLinearAccuracy(operation),
STRICT);
+
+ tolerance = isUsingEpsgFactory ? Formulas.LINEAR_TOLERANCE : 100;
+ transform = operation.getMathTransform();
+ isInverseTransformSupported = false;
+ /*
+ * Same coordinates than testProjectionAndLongitudeRotation(),
+ * but with random elevation and time which should be dropped.
+ */
+ verifyTransform(new double[] {
+ 601124.99, 2428693.45, 400, 1000,
+ 600000.00, 2420000.00, 400, 1000
+ }, new double[] {
+ 261804.30, 6218365.73,
+ 260098.74, 6205194.95
+ });
+ validate();
+ }
+
+ /**
+ * Verifies the datum shift parameters in the <cite>"NTF to WGS 84
(1)"</cite> transformation.
+ * Those parameters depends on whether an EPSG database have been used or
not.
+ *
+ * @param steps the list returned by {@link
DefaultConcatenatedOperation#getOperations()}.
+ * @param datumShiftIndex index of the datum shift operations in the
{@code steps} list.
+ * @return the {@link #isUsingEpsgFactory()} value, returned for
convenience.
+ */
+ private static boolean verifyParametersNTF(final List<? extends
CoordinateOperation> steps, final int datumShiftIndex)
+ throws FactoryException
+ {
+ if (isUsingEpsgFactory()) {
+ final SingleOperation step1 = (SingleOperation)
steps.get(datumShiftIndex);
+ final SingleOperation step2 = (SingleOperation)
steps.get(datumShiftIndex + 1);
+ assertEpsgNameAndIdentifierEqual("NTF (Paris) to NTF (1)", 1763,
step1);
+ assertEpsgNameAndIdentifierEqual("NTF to WGS 84 (1)", 1193,
step2);
+ final ParameterValueGroup p1 = step1.getParameterValues();
+ final ParameterValueGroup p2 = step2.getParameterValues();
+ assertEquals("Longitude offset", 2.5969213,
p1.parameter("Longitude offset") .doubleValue(), STRICT);
+ assertEquals("X-axis translation", -168, p2.parameter("X-axis
translation").doubleValue(), STRICT);
+ assertEquals("Y-axis translation", -60, p2.parameter("Y-axis
translation").doubleValue(), STRICT);
+ assertEquals("Z-axis translation", 320, p2.parameter("Z-axis
translation").doubleValue(), STRICT);
+ return true;
+ } else {
+ assertSame(CoordinateOperationFinder.ELLIPSOID_CHANGE,
steps.get(datumShiftIndex).getName());
+ return false;
+ }
+ }
+
+ /**
+ * Tests the conversion from Mercator projection to the Google projection.
The referencing module
+ * should detects that the conversion is something more complex that an
identity transform.
+ *
+ * @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
+ public void testMercatorToGoogle() throws ParseException,
FactoryException, TransformException {
+ final CoordinateReferenceSystem sourceCRS = parse("$Mercator");
+ final CoordinateReferenceSystem targetCRS = parse(
+ "ProjectedCRS[“WGS 84 / Pseudo-Mercator”,\n" +
+ " BaseGeodCRS[“WGS 84”,\n" +
+ " Datum[“World Geodetic System 1984”,\n" +
+ " Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]],\n" +
+ " Unit[“degree”, 0.017453292519943295]],\n" +
+ " Conversion[“Popular Visualisation Pseudo-Mercator”,\n" +
+ " Method[“Popular Visualisation Pseudo Mercator”]],\n" +
+ " CS[Cartesian, 2],\n" +
+ " Axis[“Easting (X)”, east],\n" +
+ " Axis[“Northing (Y)”, north],\n" +
+ " Unit[“metre”, 1],\n" +
+ " Id[“EPSG”, 3857]]");
+
+ final CoordinateOperation operation =
factory.createOperation(sourceCRS, targetCRS);
+ assertSame ("sourceCRS", sourceCRS, operation.getSourceCRS());
+ assertSame ("targetCRS", targetCRS, operation.getTargetCRS());
+ assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+
+ transform = operation.getMathTransform();
+ tolerance = 1;
+
+ assertFalse("Mercator to Google should not be an identity transform.",
transform.isIdentity());
+ final DirectPosition2D sourcePt = new DirectPosition2D(334000,
4840000); // Approximatively 40°N 3°W
+ final DirectPosition2D targetPt = new DirectPosition2D();
+ assertSame(targetPt, transform.transform(sourcePt, targetPt));
+ assertEquals("Easting should be unchanged", sourcePt.getX(),
targetPt.getX(), STRICT);
+ assertEquals("Expected 27 km shift", 27476, targetPt.getY() -
sourcePt.getY(), tolerance);
+ }
+}
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -217,8 +217,9 @@ import org.junit.BeforeClass;
org.apache.sis.referencing.CRSTest.class,
// Coordinate operation finders are last, since they need everything else.
- org.apache.sis.referencing.operation.CoordinateOperationFinderTest.class,
org.apache.sis.referencing.operation.CoordinateOperationRegistryTest.class,
+ org.apache.sis.referencing.operation.CoordinateOperationFinderTest.class,
+
org.apache.sis.referencing.operation.DefaultCoordinateOperationFactoryTest.class,
org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
// Geometry