Author: desruisseaux
Date: Mon Jul  6 08:59:03 2015
New Revision: 1689340

URL: http://svn.apache.org/r1689340
Log:
WKT 2: complete parsing of CoordinateOperation.

Added:
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
   (with props)
Modified:
    
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.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/DefaultCylindricalProjection.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java

Modified: 
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
 [UTF-8] Mon Jul  6 08:59:03 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/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
 [UTF-8] Mon Jul  6 08:59:03 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
 [UTF-8] Mon Jul  6 08:59:03 2015
@@ -42,6 +42,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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConicProjection.java
 [UTF-8] Mon Jul  6 08:59:03 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/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=1689340&r1=1689339&r2=1689340&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] Mon Jul  6 08:59:03 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCylindricalProjection.java
 [UTF-8] Mon Jul  6 08:59:03 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultPlanarProjection.java
 [UTF-8] Mon Jul  6 08:59:03 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java?rev=1689340&r1=1689339&r2=1689340&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultProjection.java
 [UTF-8] Mon Jul  6 08:59:03 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.

Added: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java?rev=1689340&view=auto
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
 (added)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
 [UTF-8] Mon Jul  6 08:59:03 2015
@@ -0,0 +1,72 @@
+/*
+ * 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 org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.Datum;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.Utilities;
+
+
+/**
+ * Infers a conversion of transformation path from a source CRS to a target 
CRS.
+ *
+ * This is currently only a placeholder for future SIS development (code to be 
ported from Geotk).
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+final class OperationPathFinder {
+    private OperationPathFinder() {
+    }
+
+    /**
+     * Returns {@code true} if the given CRS are using equivalent (ignoring 
metadata) datum.
+     * If the CRS are {@link CompoundCRS}, then this method verifies that all 
datum in the
+     * target CRS exists in the source CRS, but not necessarily in the same 
order.
+     * The target CRS may have less datum than the source CRS.
+     *
+     * @param sourceCRS The target CRS.
+     * @param targetCRS The source CRS.
+     * @return {@code true} if all datum in the {@code targetCRS} exists in 
the {@code sourceCRS}.
+     */
+    static boolean isConversion(final CoordinateReferenceSystem sourceCRS,
+                                final CoordinateReferenceSystem targetCRS)
+    {
+        List<SingleCRS> components = CRS.getSingleComponents(sourceCRS);
+        int n = components.size();   // Number of remaining datum from 
sourceCRS to verify.
+        final Datum[] datum = new Datum[n];
+        for (int i=0; i<n; i++) {
+            datum[i] = components.get(i).getDatum();
+        }
+        components = CRS.getSingleComponents(targetCRS);
+next:   for (int i=components.size(); --i >= 0;) {
+            final Datum d = components.get(i).getDatum();
+            for (int j=n; --j >= 0;) {
+                if (Utilities.equalsIgnoreMetadata(d, datum[j])) {
+                    System.arraycopy(datum, j+1, datum, j, --n - j);  // 
Remove the datum from the list.
+                    continue next;
+                }
+            }
+            return false;  // Datum from 'targetCRS' not found in 'sourceCRS'.
+        }
+        return true;
+    }
+}

Propchange: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/OperationPathFinder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8


Reply via email to