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/07/06 12:11:12 UTC
svn commit: r1689355 - in /sis/branches/JDK7: ./
core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/
core/sis-metadata/src/main/java/org/apache/sis/io/wkt/
core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/
core/sis-r...
Author: desruisseaux
Date: Mon Jul 6 10:11:12 2015
New Revision: 1689355
URL: http://svn.apache.org/r1689355
Log:
Merge from the JDK8 branch the completion of CoordinateOperation parsing.
Added:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
- copied unchanged from r1689341, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
Modified:
sis/branches/JDK7/ (props changed)
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 6 10:11:12 2015
@@ -1,4 +1,4 @@
/sis/branches/Android:1430670-1480699
/sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1584960-1689049
+/sis/branches/JDK8:1584960-1689354
/sis/trunk:1394364-1508466,1519089-1519674
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -24,6 +24,7 @@ import org.opengis.geometry.Envelope;
import org.opengis.metadata.Identifier;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.DerivedCRS;
import org.opengis.referencing.crs.VerticalCRS;
@@ -36,7 +37,9 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.operation.TransformException;
+import org.opengis.util.FactoryException;
import org.apache.sis.metadata.iso.extent.DefaultExtent;
import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;
@@ -92,6 +95,15 @@ public class ReferencingServices extends
public static final String PARAMETERS_KEY = "parameters";
/**
+ * The key for specifying the base type of the coordinate operation to create. This optional entry
+ * is used by {@code DefaultCoordinateOperationFactory.createSingleOperation(…)}. Apache SIS tries
+ * to infer this value automatically, but this entry may help SIS to perform a better choice in
+ * some cases. For example an "Affine" operation can be both a conversion or a transformation
+ * (the later is used in datum shift in geocentric coordinates).
+ */
+ public static final String OPERATION_TYPE_KEY = "operationType";
+
+ /**
* The key for specifying a {@linkplain org.opengis.referencing.operation.MathTransformFactory}
* instance to use for the construction of a geodetic object. This is usually not needed for CRS
* construction, except in the special case of a derived CRS created from a defining conversion.
@@ -422,6 +434,32 @@ public class ReferencingServices extends
}
/**
+ * Creates a single operation from the given properties.
+ * This method is provided here because not yet available in GeoAPI interfaces.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none.
+ * @param method The coordinate operation method (mandatory in all cases).
+ * @param factory The factory to use.
+ * @return The coordinate operation created from the given arguments.
+ * @throws FactoryException if the object creation failed.
+ *
+ * @since 0.6
+ */
+ public SingleOperation createSingleOperation(
+ final Map<String,?> properties,
+ final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS,
+ final CoordinateReferenceSystem interpolationCRS,
+ final OperationMethod method,
+ final CoordinateOperationFactory factory) throws FactoryException
+ {
+ throw moduleNotFound();
+ }
+
+ /**
* Returns the coordinate operation factory to use for the given properties and math transform factory.
* If the given properties are empty and the {@code mtFactory} is the system default, then this method
* returns the system default {@code CoordinateOperationFactory} instead of creating a new one.
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -1253,7 +1253,7 @@ final class GeodeticObjectParser extends
}
name = parent.pullString("name");
}
- OperationMethod method = parseMethod(parent, WKTKeywords.Method, WKTKeywords.Projection);
+ final OperationMethod method = parseMethod(parent, WKTKeywords.Method, WKTKeywords.Projection);
Map<String,?> properties = this.properties; // Same properties then OperationMethod, with ID removed.
/*
* Set the list of parameters.
@@ -2078,15 +2078,20 @@ final class GeodeticObjectParser extends
final CoordinateReferenceSystem sourceCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.SourceCRS);
final CoordinateReferenceSystem targetCRS = parseCoordinateReferenceSystem(element, MANDATORY, WKTKeywords.TargetCRS);
final CoordinateReferenceSystem interpolationCRS = parseCoordinateReferenceSystem(element, OPTIONAL, WKTKeywords.InterpolationCRS);
- final OperationMethod method = parseMethod(parent, WKTKeywords.Method);
- final Element accuracy = parent.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy);
- final Map<String,Object> properties = parseMetadataAndClose(parent, name, method);
+ final OperationMethod method = parseMethod(element, WKTKeywords.Method);
+ final Element accuracy = element.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy);
+ final Map<String,Object> properties = parseMetadataAndClose(element, name, method);
final ParameterValueGroup parameters = method.getParameters().createValue();
- parseParameters(parent, parameters, null, null);
+ parseParameters(element, parameters, null, null);
+ properties.put(ReferencingServices.PARAMETERS_KEY, parameters);
if (accuracy != null) {
accuracy.pullDouble("accuracy"); // TODO: share the code from EPSG factory.
accuracy.close(ignoredElements);
}
- return null; // Not yet implemented.
+ try {
+ return referencing.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, opFactory);
+ } catch (FactoryException e) {
+ throw element.parseFailed(e);
+ }
}
}
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -41,6 +41,7 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.metadata.extent.GeographicBoundingBox;
@@ -570,6 +571,39 @@ public final class ServicesForMetadata e
}
/**
+ * Creates a single operation from the given properties.
+ * This method is provided here because not yet available in GeoAPI interfaces.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none.
+ * @param method The coordinate operation method (mandatory in all cases).
+ * @param factory The factory to use.
+ * @return The coordinate operation created from the given arguments.
+ * @throws FactoryException if the object creation failed.
+ *
+ * @since 0.6
+ */
+ @Override
+ public SingleOperation createSingleOperation(
+ final Map<String,?> properties,
+ final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS,
+ final CoordinateReferenceSystem interpolationCRS,
+ final OperationMethod method,
+ final CoordinateOperationFactory factory) throws FactoryException
+ {
+ final DefaultCoordinateOperationFactory df;
+ if (factory instanceof DefaultCoordinateOperationFactory) {
+ df = (DefaultCoordinateOperationFactory) factory;
+ } else {
+ df = DefaultFactories.forBuildin(CoordinateOperationFactory.class, DefaultCoordinateOperationFactory.class);
+ }
+ return df.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, null);
+ }
+
+ /**
* Returns the coordinate operation factory to use for the given properties and math transform factory.
* If the given properties are empty and the {@code mtFactory} is the system default, then this method
* returns the system default {@code CoordinateOperationFactory} instead of creating a new one.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -23,7 +23,6 @@ import org.opengis.parameter.ParameterVa
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.OperationMethod;
@@ -168,15 +167,13 @@ public final class Affine extends Abstra
}
}
- /**
- * Returns the type of operations created by this provider.
- *
- * @return Always {@code Conversion.class} for this provider.
+ /*
+ * Do not override the 'getOperationType()' method. We want to inherit the super-type value, which is
+ * SingleOperation.class, because we do not know if this operation method will be used for a Conversion
+ * or a Transformation. When applied on geocentric coordinates, this method applies a transformation
+ * (indeeded, the EPSG method name is "Affine parametric transformation"). But this method can also
+ * be applied for unit conversions or axis swapping for examples, which are conversions.
*/
- @Override
- public Class<Conversion> getOperationType() {
- return Conversion.class;
- }
/**
* Creates a projective transform from the specified group of parameter values.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -16,12 +16,17 @@
*/
package org.apache.sis.referencing.operation;
+import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
/**
@@ -43,6 +48,24 @@ final class DefaultConicProjection exten
private static final long serialVersionUID = -8717453834398763963L;
/**
+ * Creates a projection from the given properties.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param method The coordinate operation method.
+ * @param transform Transform from positions in the source CRS to positions in the target CRS.
+ */
+ public DefaultConicProjection(final Map<String,?> properties,
+ final GeographicCRS sourceCRS,
+ final ProjectedCRS targetCRS,
+ final OperationMethod method,
+ final MathTransform transform)
+ {
+ super(properties, sourceCRS, targetCRS, method, transform);
+ }
+
+ /**
* Creates a new projection with the same values than the specified one, together with the
* specified source and target CRS. While the source conversion can be an arbitrary one, it
* is typically a defining conversion.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -26,16 +26,20 @@ import org.opengis.parameter.ParameterDe
import org.opengis.referencing.operation.*;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
import org.apache.sis.internal.referencing.MergedProperties;
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.util.collection.WeakHashSet;
+import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.iso.AbstractFactory;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.NullArgumentException;
/**
@@ -203,7 +207,7 @@ public class DefaultCoordinateOperationF
* </tr>
* <tr>
* <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
- * <td>{@link Identifier} or {@link String}</td>
+ * <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
* <td>{@link DefaultOperationMethod#getName()}</td>
* </tr>
* <tr>
@@ -213,7 +217,7 @@ public class DefaultCoordinateOperationF
* </tr>
* <tr>
* <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
- * <td>{@link Identifier} (optionally as array)</td>
+ * <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
* <td>{@link DefaultOperationMethod#getIdentifiers()}</td>
* </tr>
* <tr>
@@ -247,7 +251,7 @@ public class DefaultCoordinateOperationF
}
/**
- * Constructs a defining conversion from the given operation parameters.
+ * Creates a defining conversion from the given operation parameters.
* This conversion has no source and target CRS since those elements are usually unknown at this stage.
* The source and target CRS will become known later, at the
* {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS Derived CRS} or
@@ -308,6 +312,170 @@ public class DefaultCoordinateOperationF
}
/**
+ * Creates a transformation or conversion from the given properties.
+ * This method infers by itself if the operation to create is a
+ * {@link Transformation}, a {@link Conversion} or a {@link Projection} sub-type
+ * ({@link CylindricalProjection}, {@link ConicProjection} or {@link PlanarProjection})
+ * using the {@linkplain DefaultOperationMethod#getOperationType() information provided by the given method}.
+ *
+ * <p>The properties given in argument follow the same rules than for the
+ * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
+ * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) coordinate operation} constructor.
+ * The following table is a reminder of main (not all) properties:</p>
+ *
+ * <table class="sis">
+ * <caption>Recognized properties (non exhaustive list)</caption>
+ * <tr>
+ * <th>Property name</th>
+ * <th>Value type</th>
+ * <th>Returned by</th>
+ * </tr>
+ * <tr>
+ * <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+ * <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
+ * <td>{@link DefaultConversion#getName()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+ * <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
+ * <td>{@link DefaultConversion#getIdentifiers()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td>
+ * <td>{@link org.opengis.metadata.extent.Extent}</td>
+ * <td>{@link DefaultConversion#getDomainOfValidity()}</td>
+ * </tr>
+ * </table>
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param interpolationCRS The CRS of additional coordinates needed for the operation, or {@code null} if none.
+ * @param method The coordinate operation method (mandatory in all cases).
+ * @param transform Transform from positions in the source CRS to positions in the target CRS.
+ * @return The coordinate operation created from the given arguments.
+ * @throws FactoryException if the object creation failed.
+ *
+ * @see DefaultOperationMethod#getOperationType()
+ * @see DefaultTransformation
+ * @see DefaultConversion
+ */
+ public SingleOperation createSingleOperation(
+ final Map<String,?> properties,
+ final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS,
+ final CoordinateReferenceSystem interpolationCRS,
+ final OperationMethod method,
+ MathTransform transform) throws FactoryException
+ {
+ ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
+ ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
+ ArgumentChecks.ensureNonNull("method", method);
+ /*
+ * Undocumented (for now) feature: if the 'transform' argument is null but parameters are
+ * found in the given properties, create the MathTransform instance from those parameters.
+ */
+ if (transform == null) {
+ final ParameterValueGroup parameters = Containers.property(properties,
+ ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class);
+ if (parameters == null) {
+ throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, "transform"));
+ }
+ transform = mtFactory.createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());
+ }
+ /*
+ * The "operationType" property is currently undocumented. The intend is to help this factory method in
+ * situations where the given operation method is not an Apache SIS implementation or does not override
+ * getOperationType(), or the method is ambiguous (e.g. "Affine" can be used for both a transformation
+ * or a conversion).
+ *
+ * If we have both a 'baseType' and a Method.getOperationType(), take the most specific type.
+ * An exception will be thrown if the two types are incompatible.
+ */
+ Class<?> baseType = Containers.property(properties, ReferencingServices.OPERATION_TYPE_KEY, Class.class);
+ if (baseType == null) {
+ baseType = SingleOperation.class;
+ }
+ if (method instanceof DefaultOperationMethod) {
+ final Class<? extends SingleOperation> c = ((DefaultOperationMethod) method).getOperationType();
+ if (c != null) { // Paranoiac check (above method should not return null).
+ if (baseType.isAssignableFrom(c)) {
+ baseType = c;
+ } else if (!c.isAssignableFrom(baseType)) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1,
+ ReferencingServices.OPERATION_TYPE_KEY));
+ }
+ }
+ }
+ /*
+ * If the base type is still abstract (probably because it was not specified neither in the given OperationMethod
+ * or in the properties), then try to find a concrete type using the following rules derived from the definitions
+ * given in ISO 19111:
+ *
+ * - If the two CRS uses the same datum (ignoring metadata), assume that we have a Conversion.
+ * - Otherwise we have a datum change, which implies that we have a Transformation.
+ *
+ * In the case of Conversion, we can specialize one step more if the conversion is going from a geographic CRS
+ * to a projected CRS. It may seems that we should check if ProjectedCRS.getBaseCRS() is equals (ignoring meta
+ * data) to source CRS. But we already checked the datum, which is the important part. The axis order and unit
+ * could be different, which we want to allow.
+ */
+ if (baseType == SingleOperation.class) {
+ if (OperationPathFinder.isConversion(sourceCRS, targetCRS)) {
+ if (interpolationCRS == null && sourceCRS instanceof GeographicCRS
+ && targetCRS instanceof ProjectedCRS)
+ {
+ baseType = Projection.class;
+ } else {
+ baseType = Conversion.class;
+ }
+ } else {
+ baseType = Transformation.class;
+ }
+ }
+ /*
+ * Now create the coordinate operation of the requested type. If we can not find a concrete class for the
+ * requested type, we will instantiate an SingleOperation in last resort. The later action is a departure
+ * from ISO 19111 since 'SingleOperation' is conceptually abstract. But we do that as a way to said that
+ * we are missing this important piece of information but still go ahead.
+ *
+ * It is unconvenient to guarantee that the created operation is an instance of 'baseType' since the user
+ * could have specified an implementation class or a custom sub-interface. We will perform the type check
+ * only after object creation.
+ */
+ final AbstractSingleOperation op;
+ if (Transformation.class.isAssignableFrom(baseType)) {
+ op = new DefaultTransformation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
+ } else if (Projection.class.isAssignableFrom(baseType)) {
+ ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS);
+ ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS .class, targetCRS);
+ if (interpolationCRS != null) {
+ throw new IllegalArgumentException(Errors.format(
+ Errors.Keys.ForbiddenAttribute_2, "interpolationCRS", baseType));
+ }
+ final GeographicCRS baseCRS = (GeographicCRS) sourceCRS;
+ final ProjectedCRS crs = (ProjectedCRS) targetCRS;
+ if (CylindricalProjection.class.isAssignableFrom(baseType)) {
+ op = new DefaultCylindricalProjection(properties, baseCRS, crs, method, transform);
+ } else if (ConicProjection.class.isAssignableFrom(baseType)) {
+ op = new DefaultConicProjection(properties, baseCRS, crs, method, transform);
+ } else if (PlanarProjection.class.isAssignableFrom(baseType)) {
+ op = new DefaultPlanarProjection(properties, baseCRS, crs, method, transform);
+ } else {
+ op = new DefaultProjection(properties, baseCRS, crs, method, transform);
+ }
+ } else if (Conversion.class.isAssignableFrom(baseType)) {
+ op = new DefaultConversion(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
+ } else { // See above comment about this last-resort fallback.
+ op = new AbstractSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
+ }
+ if (!baseType.isInstance(op)) {
+ throw new FactoryException(Errors.format(Errors.Keys.CanNotInstantiate_1, baseType));
+ }
+ return pool.unique(op);
+ }
+
+ /**
* Creates an ordered sequence of two or more single coordinate operations.
* The sequence of operations is constrained by the requirement that the source coordinate reference system
* of step (<var>n</var>+1) must be the same as the target coordinate reference system of step (<var>n</var>).
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -16,12 +16,17 @@
*/
package org.apache.sis.referencing.operation;
+import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.CylindricalProjection;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
/**
@@ -43,6 +48,24 @@ final class DefaultCylindricalProjection
private static final long serialVersionUID = -969486613826553580L;
/**
+ * Creates a projection from the given properties.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param method The coordinate operation method.
+ * @param transform Transform from positions in the source CRS to positions in the target CRS.
+ */
+ public DefaultCylindricalProjection(final Map<String,?> properties,
+ final GeographicCRS sourceCRS,
+ final ProjectedCRS targetCRS,
+ final OperationMethod method,
+ final MathTransform transform)
+ {
+ super(properties, sourceCRS, targetCRS, method, transform);
+ }
+
+ /**
* Creates a new projection with the same values than the specified one, together with the
* specified source and target CRS. While the source conversion can be an arbitrary one, it
* is typically a defining conversion.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -16,12 +16,17 @@
*/
package org.apache.sis.referencing.operation;
+import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.PlanarProjection;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
/**
@@ -43,6 +48,24 @@ final class DefaultPlanarProjection exte
private static final long serialVersionUID = 8171256287775067736L;
/**
+ * Creates a projection from the given properties.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param method The coordinate operation method.
+ * @param transform Transform from positions in the source CRS to positions in the target CRS.
+ */
+ public DefaultPlanarProjection(final Map<String,?> properties,
+ final GeographicCRS sourceCRS,
+ final ProjectedCRS targetCRS,
+ final OperationMethod method,
+ final MathTransform transform)
+ {
+ super(properties, sourceCRS, targetCRS, method, transform);
+ }
+
+ /**
* Creates a new projection with the same values than the specified one, together with the
* specified source and target CRS. While the source conversion can be an arbitrary one, it
* is typically a defining conversion.
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -16,10 +16,13 @@
*/
package org.apache.sis.referencing.operation;
+import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.Projection;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.crs.GeographicCRS;
@@ -58,6 +61,24 @@ class DefaultProjection extends DefaultC
private static final long serialVersionUID = -7176751851369816864L;
/**
+ * Creates a projection from the given properties.
+ *
+ * @param properties The properties to be given to the identified object.
+ * @param sourceCRS The source CRS.
+ * @param targetCRS The target CRS.
+ * @param method The coordinate operation method.
+ * @param transform Transform from positions in the source CRS to positions in the target CRS.
+ */
+ public DefaultProjection(final Map<String,?> properties,
+ final GeographicCRS sourceCRS,
+ final ProjectedCRS targetCRS,
+ final OperationMethod method,
+ final MathTransform transform)
+ {
+ super(properties, sourceCRS, targetCRS, null, method, transform);
+ }
+
+ /**
* Creates a new projection with the same values than the specified one, together with the
* specified source and target CRS. While the source conversion can be an arbitrary one, it
* is typically a defining conversion.
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -17,6 +17,7 @@
package org.apache.sis.internal.referencing.provider;
import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.test.DependsOnMethod;
@@ -38,6 +39,17 @@ import static org.apache.sis.test.Metada
@DependsOn(org.apache.sis.parameter.TensorValuesTest.class)
public final strictfp class AffineTest extends TestCase {
/**
+ * Verifies that {@link Affine#getOperationType()} is {@link SingleOperation}.
+ * The {@code Affine} class can not return one of the above, because we do not
+ * know if this operation method will be used for a transformation ora conversion
+ * (it can be used for both).
+ */
+ @Test
+ public void testOperationType() {
+ assertEquals(SingleOperation.class, new Affine().getOperationType());
+ }
+
+ /**
* Tests {@link Affine#getParameters()} on a standard EPSG:9624 instance.
*/
@Test
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java?rev=1689355&r1=1689354&r2=1689355&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java [UTF-8] Mon Jul 6 10:11:12 2015
@@ -120,7 +120,7 @@ public final strictfp class DefaultMathT
assertFalse(transforms .isEmpty());
assertFalse(conversions.isEmpty());
assertFalse(projections.isEmpty());
- assertTrue (conversions.contains(factory.getOperationMethod(Constants.AFFINE)));
+ assertTrue (transforms.contains(factory.getOperationMethod(Constants.AFFINE)));
/*
* Following tests will force instantiation of all remaining OperationMethod.
*/