sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1738874 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/ main/java/org/apache/sis/referencing/datum/ main/java/org/apache/sis/referencing/operat...
Date Tue, 12 Apr 2016 22:23:32 GMT
Author: desruisseaux
Date: Tue Apr 12 22:23:32 2016
New Revision: 1738874

URL: http://svn.apache.org/viewvc?rev=1738874&view=rev
Log:
Rename CoordinateOperationInference as CoordinateOperationFinder and define
as a subclass of package-privated CoordinateOperationRegistry for enabling
the search in EPSG database before to try to infer the coordinate operation
by itself.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
      - copied, changed from r1738873, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
      - copied, changed from r1738873, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
Removed:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3DtoVertical.txt
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationContext.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.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/SubOperationInfo.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.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/provider/Geographic3DtoVertical.txt
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3DtoVertical.txt?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3DtoVertical.txt [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3DtoVertical.txt [UTF-8] Tue Apr 12 22:23:32 2016
@@ -5,7 +5,7 @@ but it should be only in contexts where
 dimensions in an "interpolation CRS".  This happen in the following
 method:
 
-CoordinateOperationInference.createOperationStep(GeodeticCRS, VerticalCRS)
+CoordinateOperationFinder.createOperationStep(GeodeticCRS, VerticalCRS)
 
 The above method does inline the work of what would have been a
 "Geographic 3D to ellipsoidal height" operation if it existed.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -301,12 +301,11 @@ public final class CRS extends Static {
         ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
         CoordinateOperationContext context = null;
         if (areaOfInterest != null) {
-            final DefaultGeographicBoundingBox bbox = DefaultGeographicBoundingBox.castOrCopy(areaOfInterest);
-            if (bbox.isEmpty()) {
+            if (areaOfInterest instanceof DefaultGeographicBoundingBox && ((DefaultGeographicBoundingBox) areaOfInterest).isEmpty()) {
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "areaOfInterest"));
             }
             context = new CoordinateOperationContext();
-            context.setGeographicBoundingBox(bbox);
+            context.setAreaOfInterest(areaOfInterest);
         }
         return CoordinateOperations.factory().createOperation(sourceCRS, targetCRS, context);
     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -238,7 +238,7 @@ public class BursaWolfParameters extends
      *
      * <p><b>Maintenance note:</b>
      * if the above policy regarding prime meridians is modified, then some {@code createOperationStep(…)} method
-     * implementations in {@link org.apache.sis.referencing.operation.CoordinateOperationInference} may need to be
+     * implementations in {@link org.apache.sis.referencing.operation.CoordinateOperationFinder} may need to be
      * revisited. See especially the methods creating a transformation between a pair of {@code GeocentricCRS} or
      * between a pair of {@code GeographicCRS} (tip: search for {@code DefaultGeodeticDatum}).</p>
      *

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationContext.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationContext.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationContext.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationContext.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -19,11 +19,15 @@ package org.apache.sis.referencing.opera
 import java.io.Serializable;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.referencing.operation.CoordinateOperation;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
 import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.ArgumentChecks;
 
+// Branch-dependent imports
+import java.util.function.Predicate;
+
 
 /**
  * Optional information about the context in which a requested coordinate operation will be used.
@@ -66,11 +70,6 @@ public class CoordinateOperationContext
     private Extent areaOfInterest;
 
     /**
-     * The geographic component of the area of interest, computed when first needed.
-     */
-    private transient GeographicBoundingBox bbox;
-
-    /**
      * The desired accuracy in metres, or 0 for the best accuracy available.
      * See {@link #getDesiredAccuracy()} for more details about what we mean by <cite>"best accuracy"</cite>.
      */
@@ -99,6 +98,8 @@ public class CoordinateOperationContext
      * Returns the spatio-temporal area of interest, or {@code null} if none.
      *
      * @return The spatio-temporal area of interest, or {@code null} if none.
+     *
+     * @see Extents#getGeographicBoundingBox(Extent)
      */
     public Extent getAreaOfInterest() {
         return areaOfInterest;
@@ -109,32 +110,24 @@ public class CoordinateOperationContext
      *
      * @param area The spatio-temporal area of interest, or {@code null} if none.
      */
-    public void setAreaOfInterest(final Extent area) {
-        areaOfInterest = area;
-    }
-
-    /**
-     * Returns the geographic component of the area of interest, or {@code null} if none.
-     * This convenience method extracts the bounding box from the spatio-temporal {@link Extent}.
-     *
-     * @return The geographic area of interest, or {@code null} if none.
-     */
-    public GeographicBoundingBox getGeographicBoundingBox() {
-        if (bbox == null) {
-            bbox = Extents.getGeographicBoundingBox(areaOfInterest);
+    public void setAreaOfInterest(Extent area) {
+        if (area != null) {
+            area = new DefaultExtent(area);
         }
-        return bbox;
+        areaOfInterest = area;
     }
 
     /**
      * Sets the geographic component of the area of interest, or {@code null} if none.
      * This convenience method set the bounding box into the spatio-temporal {@link Extent}.
      *
+     * <p>The reverse operation can be done with <code>{@linkplain Extents#getGeographicBoundingBox(Extent)
+     * Extents.getGeographicBoundingBox}({@linkplain #getAreaOfInterest()})</code>.</p>
+     *
      * @param area The geographic area of interest, or {@code null} if none.
      */
-    public void setGeographicBoundingBox(final GeographicBoundingBox area) {
+    public void setAreaOfInterest(final GeographicBoundingBox area) {
         areaOfInterest = setGeographicBoundingBox(areaOfInterest, area);
-        bbox = area;
     }
 
     /**
@@ -177,4 +170,13 @@ public class CoordinateOperationContext
         ArgumentChecks.ensurePositive("accuracy", accuracy);
         desiredAccuracy = accuracy;
     }
+
+    /**
+     * Returns a filter that can be used for applying additional restrictions on the coordinate operation.
+     *
+     * @todo Not yet implemented.
+     */
+    Predicate<CoordinateOperation> getOperationFilter() {
+        return null;
+    }
 }

Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java (from r1738873, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java&r1=1738873&r2=1738874&rev=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -30,6 +30,7 @@ import org.opengis.referencing.crs.*;
 import org.opengis.referencing.datum.*;
 import org.opengis.referencing.operation.*;
 import org.opengis.metadata.Identifier;
+import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.internal.metadata.AxisDirections;
 import org.apache.sis.internal.metadata.VerticalDatumTypes;
@@ -62,7 +63,37 @@ import static org.apache.sis.util.Utilit
 
 
 /**
- * Infers a conversion of transformation path from a source CRS to a target CRS.
+ * Finds a conversion or transformation path from a source CRS to a target CRS.
+ * This class implements two strategies for searching the coordinate operation:
+ *
+ * <ol class="verbose">
+ *   <li>When <code>{@linkplain #createOperation createOperation}(sourceCRS, targetCRS)</code> is invoked,
+ *       this class first {@linkplain org.apache.sis.referencing.factory.IdentifiedObjectFinder tries to
+ *       find the authority codes} for the given source and target CRS. If such codes are found, they are
+ *       {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory#createFromCoordinateReferenceSystemCodes
+ *       submitted to a registry of coordinate operations}. If an operation is found, it will be returned.
+ *
+ *       <div class="note"><b>Note:</b> the above is known as the <cite>late-binding</cite> approach.
+ *       The late-binding approach allows the authority to define better suited operations than what
+ *       we would get if we were transforming everything from and to a pivot system (e.g. WGS84).
+ *       In addition, this approach provides useful informations like the coordinate operation
+ *       {@linkplain AbstractCoordinateOperation#getScope() scope} and
+ *       {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity},
+ *       {@linkplain AbstractCoordinateOperation#getCoordinateOperationAccuracy() accuracy}.</div>
+ *   </li>
+ *   <li>If the above authority factory does not know about the specified CRS, then this class tries to
+ *       infer the coordinate operation by itself. The CRS type is examined and the work is dispatched
+ *       to one or many of the {@code createOperationStep(…)} protected methods defined in this class.
+ *       Those methods use properties associated to the CRS, including {@code BOUNDCRS} or {@code TOWGS84}
+ *       elements found in <cite>Well Known Text</cite> (WKT).
+ *
+ *       <div class="note"><b>Note:</b> the use of elements like {@code TOWGS84} is known as the
+ *       <cite>early-binding</cite> approach. The operation found by this approach may be sub-optimal.
+ *       The early-binding approach is used only as a fallback when the late-binding approach gave no result.</div>
+ *   </li>
+ * </ol>
+ *
+ * <div class="section">Customization</div>
  * Instances of this class are created by {@link DefaultCoordinateOperationFactory}.
  * The only public method is {@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)},
  * which dispatches its work to the {@code createOperationStep(…)} protected methods.
@@ -81,7 +112,7 @@ import static org.apache.sis.util.Utilit
  *
  * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
  */
-public class CoordinateOperationInference extends CoordinateOperationFinder {
+public class CoordinateOperationFinder extends CoordinateOperationRegistry {
     /**
      * The accuracy threshold (in metres) for allowing the use of Molodensky approximation instead than the
      * Geocentric Translation method. The accuracy of datum shifts with Molodensky approximation is about 5
@@ -94,13 +125,6 @@ public class CoordinateOperationInferenc
     private static final double MOLODENSKY_ACCURACY = 5;
 
     /**
-     * The desired accuracy in metres, or 0 for the best accuracy available.
-     *
-     * @see #MOLODENSKY_ACCURACY
-     */
-    private final double desiredAccuracy;
-
-    /**
      * Identifiers used as the basis for identifier of CRS used as an intermediate step.
      * The values can be of two kinds:
      *
@@ -124,23 +148,34 @@ public class CoordinateOperationInferenc
     /**
      * Creates a new instance for the given factory and context.
      *
-     * @param factory The factory to use for creating coordinate operations.
-     * @param context The area of interest and desired accuracy, or {@code null} if none.
-     */
-    public CoordinateOperationInference(final CoordinateOperationFactory factory,
-                                        final CoordinateOperationContext context)
+     * @param  registry  the factory to use for creating operations as defined by authority, or {@code null} if none.
+     * @param  factory   the factory to use for creating operations not found in the registry.
+     * @param  context   the area of interest and desired accuracy, or {@code null} if none.
+     * @throws FactoryException if an error occurred while initializing this {@code CoordinateOperationFinder}.
+     */
+    public CoordinateOperationFinder(final CoordinateOperationAuthorityFactory registry,
+                                     final CoordinateOperationFactory          factory,
+                                     final CoordinateOperationContext          context) throws FactoryException
     {
-        super(factory, context);
+        super(registry, factory, context);
         identifierOfStepCRS = new HashMap<>(8);
         previousSearches    = new HashMap<>(8);
-        desiredAccuracy     = (context != null) ? context.getDesiredAccuracy() : 0;
     }
 
     /**
      * Infers an operation for conversion or transformation between two coordinate reference systems.
-     * This method inspects the given CRS and delegates the work to one or many {@code createOperationStep(…)} methods.
-     * Note that some {@code createOperationStep(…)} methods may callback this {@code createOperation(…)} method with
-     * another source or target CRS.
+     * If a non-null authority factory – the <cite>registry</cite> – has been specified at construction time,
+     * this method will first query that factory (<cite>late-binding</cite> approach – see class javadoc).
+     * If no operation has been found in the registry or if no registry has been specified to the constructor,
+     * this method inspects the given CRS and delegates the work to one or many {@code createOperationStep(…)}
+     * methods (<cite>early-binding</cite> approach).
+     *
+     * <p>At first, this method is invoked with the {@code sourceCRS} and {@code targetCRS} arguments given to the
+     * {@link DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem,
+     * CoordinateOperationContext) CoordinateOperationFactory.createOperation(…)} method. But then, this method may
+     * be invoked recursively by some {@code createOperationStep(…)} methods with different source or target CRS,
+     * for example in order to process the {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS#getBaseCRS()
+     * base geographic CRS} of a projected CRS.</p>
      *
      * @param  sourceCRS  input coordinate reference system.
      * @param  targetCRS  output coordinate reference system.
@@ -162,11 +197,16 @@ public class CoordinateOperationInferenc
         if (previousSearches.put(key, Boolean.TRUE) != null) {
             throw new FactoryException(Errors.format(Errors.Keys.RecursiveCreateCallForCode_2, CoordinateOperation.class, key));
         }
+        GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(areaOfInterest);
         if (bbox == null) {
             bbox = Extents.intersection(CRS.getGeographicBoundingBox(sourceCRS),
                                         CRS.getGeographicBoundingBox(targetCRS));
             areaOfInterest = CoordinateOperationContext.setGeographicBoundingBox(areaOfInterest, bbox);
         }
+        if (registry != null) {
+            final CoordinateOperation op = super.createOperation(sourceCRS, targetCRS);
+            if (op != null) return op;
+        }
         ////////////////////////////////////////////////////////////////////////////////
         ////                                                                        ////
         ////                       Derived  →  any Single CRS                       ////

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -30,7 +30,10 @@ import javax.measure.converter.Conversio
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.metadata.Identifier;
-import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -40,6 +43,7 @@ import org.opengis.referencing.operation
 
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.cs.CoordinateSystems;
@@ -47,13 +51,18 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
+import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
 import org.apache.sis.referencing.factory.MissingFactoryResourceException;
 import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.internal.referencing.CoordinateOperations;
+import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Citations;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.Classes;
@@ -61,38 +70,83 @@ import org.apache.sis.util.Deprecable;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.collection.BackingStoreException;
+import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.resources.Errors;
 
 // Branch-dependent imports
+import java.util.Objects;
 import java.util.function.Predicate;
 
 
 /**
- * Searches coordinate operations in a registry maintained by an authority (typically EPSG).
- * Authority factory may help to find transformation paths not available otherwise
- * (often determined from empirical parameters).
- * Authority factories can also provide additional informations like the
- * {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity},
- * {@linkplain AbstractCoordinateOperation#getScope() scope} and
- * {@linkplain AbstractCoordinateOperation#getCoordinateOperationAccuracy() accuracy}.
+ * Base class of code that search for coordinate operation, either by looking in a registry maintained by an authority
+ * or by trying to infer the coordinate operation by itself. For maintenance and testing purposes, we separate the task
+ * in two classes for the two main strategies used for finding coordinate operations:
  *
- * <p>When <code>{@linkplain #createOperation createOperation}(sourceCRS, targetCRS)</code> is invoked, this class
- * fetches the authority codes for source and target CRS and submits them to the authority factory through a call
- * to its <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
+ * <ul>
+ *   <li>{@code CoordinateOperationRegistry} implements the <cite>late-binding</cite> approach
+ *       (i.e. search coordinate operation paths specified by authorities like the ones listed
+ *       in the EPSG dataset), which is the preferred approach.</li>
+ *   <li>{@link CoordinateOperationFinder} adds an <cite>early-binding</cite> approach
+ *       (i.e. find a coordinate operation path by inspecting the properties associated to the CRS).
+ *       That approach is used only as a fallback when the late-binding approach gave no result.</li>
+ * </ul>
+ *
+ * When <code>{@linkplain #createOperation createOperation}(sourceCRS, targetCRS)</code> is invoked,
+ * this class fetches the authority codes for source and target CRS and submits them to the authority factory
+ * through a call to its <code>{@linkplain GeodeticAuthorityFactory#createFromCoordinateReferenceSystemCodes
  * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method.
  * If the authority factory does not know about the specified CRS,
- * then {@link CoordinateOperationInference} is used as a fallback.</p>
+ * then {@link CoordinateOperationFinder} will use its own fallback.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
  */
-final class CoordinateOperationRegistry extends CoordinateOperationFinder {
+class CoordinateOperationRegistry {
+    /**
+     * The identifier for an identity operation.
+     */
+    private static final Identifier IDENTITY = createIdentifier(Vocabulary.Keys.Identity);
+
+    /**
+     * The identifier for conversion using an affine transform for axis swapping and/or unit conversions.
+     */
+    static final Identifier AXIS_CHANGES = createIdentifier(Vocabulary.Keys.AxisChanges);
+
     /**
-     * The registry authority. This is typically EPSG.
+     * The identifier for a transformation which is a datum shift without {@link BursaWolfParameters}.
+     * Only the changes in ellipsoid axis-length are taken in account.
+     * Such ellipsoid shifts are approximative and may have 1 kilometre error.
+     *
+     * @see org.apache.sis.internal.referencing.PositionalAccuracyConstan#DATUM_SHIFT_OMITTED
      */
-    private final Citation authority;
+    static final Identifier ELLIPSOID_CHANGE = createIdentifier(Vocabulary.Keys.EllipsoidChange);
+
+    /**
+     * The identifier for a transformation which is a datum shift.
+     *
+     * @see org.apache.sis.internal.referencing.PositionalAccuracyConstant#DATUM_SHIFT_APPLIED
+     */
+    static final Identifier DATUM_SHIFT = createIdentifier(Vocabulary.Keys.DatumShift);
+
+    /**
+     * The identifier for a geocentric conversion.
+     */
+    static final Identifier GEOCENTRIC_CONVERSION = createIdentifier(Vocabulary.Keys.GeocentricConversion);
+
+    /**
+     * The identifier for an inverse operation.
+     */
+    private static final Identifier INVERSE_OPERATION = createIdentifier(Vocabulary.Keys.InverseOperation);
+
+    /**
+     * Creates an identifier in the Apache SIS namespace for the given vocabulary key.
+     */
+    private static Identifier createIdentifier(final short key) {
+        return new NamedIdentifier(org.apache.sis.metadata.iso.citation.Citations.SIS, Vocabulary.formatInternational(key));
+    }
 
     /**
      * The object to use for finding authority codes.
@@ -100,29 +154,79 @@ final class CoordinateOperationRegistry
     private final IdentifiedObjectFinder codeFinder;
 
     /**
-     * The authority factory to use for creating new operations.
+     * The factory to use for creating operations as defined by authority, or {@code null} if none.
+     * This is the factory used by the <cite>late-binding</cite> approach.
+     */
+    protected final CoordinateOperationAuthorityFactory registry;
+
+    /**
+     * The factory to use for creating coordinate operations not found in the registry.
+     * This is the factory used by the <cite>early-binding</cite> approach.
+     */
+    protected final CoordinateOperationFactory factory;
+
+    /**
+     * Used only when we need a SIS-specific method.
      */
-    private final CoordinateOperationAuthorityFactory registry;
+    final DefaultCoordinateOperationFactory factorySIS;
 
     /**
-     * Filter the coordinate operation, or {@code null} if none.
+     * The spatio-temporal area of interest, or {@code null} if none.
+     * When a new {@code CoordinateOperationFinder} instance is created with a non-null
+     * {@link CoordinateOperationContext}, the context is used for initializing this value.
+     * After initialization, this field may be updated as {@code CoordinateOperationFinder}
+     * progresses in its search for a coordinate operation.
+     *
+     * @see CoordinateOperationContext#getAreaOfInterest()
+     */
+    protected Extent areaOfInterest;
+
+    /**
+     * The desired accuracy in metres, or 0 for the best accuracy available.
+     *
+     * @see CoordinateOperationContext#getDesiredAccuracy()
      */
-    private final Predicate<CoordinateOperation> filter;
+    protected double desiredAccuracy;
 
     /**
-     * Creates a new finder for the given factory.
+     * A filter that can be used for applying additional restrictions on the coordinate operation,
+     * or {@code null} if none.
+     */
+    private Predicate<CoordinateOperation> filter;
+
+    /**
+     * Creates a new instance for the given factory and context.
+     *
+     * @param  registry  the factory to use for creating operations as defined by authority.
+     * @param  factory   the factory to use for creating operations not found in the registry.
+     * @param  context   the area of interest and desired accuracy, or {@code null} if none.
+     * @throws FactoryException if an error occurred while initializing this {@link CoordinateOperationRegistry}.
      */
-    CoordinateOperationRegistry(final DefaultCoordinateOperationFactory   factory,
-                                final CoordinateOperationAuthorityFactory registry,
+    CoordinateOperationRegistry(final CoordinateOperationAuthorityFactory registry,
+                                final CoordinateOperationFactory          factory,
                                 final CoordinateOperationContext          context) throws FactoryException
     {
-        super(factory, context);
+        ArgumentChecks.ensureNonNull("factory", factory);
         this.registry = registry;
-        authority  = registry.getAuthority();
-        codeFinder = IdentifiedObjects.newFinder(Citations.getIdentifier(authority, false));
-        codeFinder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
-        codeFinder.setIgnoringAxes(true);
-        filter = null;  // TODO
+        this.factory  = factory;
+        factorySIS    = (factory instanceof DefaultCoordinateOperationFactory)
+                        ? (DefaultCoordinateOperationFactory) factory : CoordinateOperations.factory();
+        if (registry != null) {
+            if (registry instanceof GeodeticAuthorityFactory) {
+                codeFinder = ((GeodeticAuthorityFactory) registry).newIdentifiedObjectFinder();
+            } else {
+                codeFinder = IdentifiedObjects.newFinder(Citations.getIdentifier(registry.getAuthority(), false));
+            }
+            codeFinder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
+            codeFinder.setIgnoringAxes(true);
+        } else {
+            codeFinder = null;
+        }
+        if (context != null) {
+            areaOfInterest  = context.getAreaOfInterest();
+            desiredAccuracy = context.getDesiredAccuracy();
+            filter          = context.getOperationFilter();
+        }
     }
 
     /**
@@ -130,24 +234,32 @@ final class CoordinateOperationRegistry
      * This method does not trust the code given by the user in its CRS - we verify it.
      */
     private String findCode(final CoordinateReferenceSystem crs) throws FactoryException {
-        final Identifier identifier = IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs), authority);
+        final Identifier identifier = IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs), null);
         return (identifier != null) ? identifier.getCode() : null;
     }
 
     /**
-     * Returns an operation for conversion or transformation between two coordinate reference systems.
-     * The default implementation extracts the authority code from the supplied {@code sourceCRS} and
-     * {@code targetCRS}, and submit them to the
+     * Finds or infers an operation for conversion or transformation between two coordinate reference systems.
+     * {@code CoordinateOperationRegistry} implements the <cite>late-binding</cite> approach (see definition
+     * of terms in class javadoc) by extracting the authority codes from the supplied {@code sourceCRS} and
+     * {@code targetCRS}, then by submitting those codes to the
      * <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
-     * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> methods.
+     * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method.
      * If no operation is found for those codes, then this method returns {@code null}.
+     * Note that it does not mean that no path exist;
+     * it only means that it was not defined explicitely in the registry.
      *
-     * @param  sourceCRS  source coordinate reference system.
-     * @param  targetCRS  target coordinate reference system.
+     * <p>If the subclass implements the <cite>early-binding</cite> approach (which is the fallback if late-binding
+     * gave no result), then this method should never return {@code null} since there is no other fallback.
+     * Instead, this method may throw an {@link OperationNotFoundException}.</p>
+     *
+     * @param  sourceCRS  input coordinate reference system.
+     * @param  targetCRS  output coordinate reference system.
      * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}, or {@code null}
      *         if no such operation is explicitly defined in the underlying database.
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
      */
-    @Override
     public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
                                                final CoordinateReferenceSystem targetCRS)
             throws FactoryException
@@ -231,9 +343,9 @@ final class CoordinateOperationRegistry
              * are equal while the CRS are not. Such situation should be illegal, but unfortunately it still
              * happen because many softwares are not compliant with EPSG definition of axis order.   In such
              * cases we will need to compute a transform from sourceCRS to targetCRS ignoring the source and
-             * target codes.   The CoordinateOperationInference class can do that, providing that we prevent
-             * this CoordinateOperationRegistry to (legitimately) claims that the operation from sourceCode
-             * to targetCode is the identity transform.
+             * target codes. The CoordinateOperationFinder class can do that, providing that we prevent this
+             * CoordinateOperationRegistry to (legitimately) claims that the operation from sourceCode to
+             * targetCode is the identity transform.
              */
             return null;
         }
@@ -257,7 +369,7 @@ final class CoordinateOperationRegistry
             /*
              * sourceCode or targetCode is unknown to the underlying authority factory.
              * Ignores the exception and fallback on the generic algorithm provided by
-             * CoordinateOperationInference.
+             * CoordinateOperationFinder.
              */
             log(exception);
             return null;
@@ -301,7 +413,9 @@ final class CoordinateOperationRegistry
                 if (isDeprecated && stopAtFirstDeprecated) {
                     break;
                 }
-                final double area = Extents.area(Extents.intersection(bbox, Extents.getGeographicBoundingBox(candidate.getDomainOfValidity())));
+                final double area = Extents.area(Extents.intersection(
+                        Extents.getGeographicBoundingBox(areaOfInterest),
+                        Extents.getGeographicBoundingBox(candidate.getDomainOfValidity())));
                 if (bestChoice == null || area >= largestArea) {
                     final double accuracy = CRS.getLinearAccuracy(candidate);
                     if (bestChoice == null || area != largestArea || accuracy < finestAccuracy) {
@@ -334,18 +448,34 @@ final class CoordinateOperationRegistry
     }
 
     /**
-     * Returns the inverse of the specified operation.
+     * Creates the inverse of the given single operation.
+     */
+    final CoordinateOperation inverse(final SingleOperation op) throws NoninvertibleTransformException, FactoryException {
+        final CoordinateReferenceSystem sourceCRS = op.getSourceCRS();
+        final CoordinateReferenceSystem targetCRS = op.getTargetCRS();
+        final MathTransform transform = op.getMathTransform().inverse();
+        Class<? extends CoordinateOperation> type = null;
+        if (op instanceof Transformation)  type = Transformation.class;
+        else if (op instanceof Conversion) type = Conversion.class;
+        final Map<String,Object> properties = properties(INVERSE_OPERATION);
+        InverseOperationMethod.putParameters(op, properties);
+        return createFromMathTransform(properties, targetCRS, sourceCRS,
+                transform, InverseOperationMethod.create(op.getMethod()), null, type);
+    }
+
+    /**
+     * Creates the inverse of the given operation, which may be single or compound.
      *
      * @param  operation The operation to invert, or {@code null}.
      * @return The inverse of {@code operation}, or {@code null} if none.
      * @throws NoninvertibleTransformException if the operation is not invertible.
      * @throws FactoryException if the operation creation failed for an other reason.
      */
-    protected CoordinateOperation inverse(final CoordinateOperation operation)
+    private CoordinateOperation inverse(final CoordinateOperation operation)
             throws NoninvertibleTransformException, FactoryException
     {
         if (operation instanceof SingleOperation) {
-            return super.inverse((SingleOperation) operation);
+            return inverse((SingleOperation) operation);
         }
         if (operation instanceof ConcatenatedOperation) {
             final List<? extends CoordinateOperation> operations = ((ConcatenatedOperation) operation).getOperations();
@@ -721,15 +851,143 @@ final class CoordinateOperationRegistry
     }
 
     /**
+     * Returns the specified identifier in a map to be given to coordinate operation constructors.
+     * In the special case where the {@code name} identifier is {@link #DATUM_SHIFT} or {@link #ELLIPSOID_CHANGE},
+     * the map will contains extra informations like positional accuracy.
+     *
+     * <div class="note"><b>Note:</b>
+     * in the datum shift case, an operation version is mandatory but unknown at this time.
+     * However, we noticed that the EPSG database do not always defines a version neither.
+     * Consequently, the Apache SIS implementation relaxes the rule requiring an operation
+     * version and we do not try to provide this information here for now.</div>
+     *
+     * @param  name  The name to put in a map.
+     * @return a modifiable map containing the given name. Callers can put other entries in this map.
+     */
+    static Map<String,Object> properties(final Identifier name) {
+        final Map<String,Object> properties = new HashMap<>(4);
+        properties.put(CoordinateOperation.NAME_KEY, name);
+        if ((name == DATUM_SHIFT) || (name == ELLIPSOID_CHANGE)) {
+            properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, new PositionalAccuracy[] {
+                      (name == DATUM_SHIFT) ? PositionalAccuracyConstant.DATUM_SHIFT_APPLIED
+                                            : PositionalAccuracyConstant.DATUM_SHIFT_OMITTED});
+        }
+        return properties;
+    }
+
+    /**
+     * Creates a coordinate operation from a math transform.
+     * The method performs the following steps:
+     *
+     * <ul class="verbose">
+     *   <li>If the given {@code transform} is already an instance of {@code CoordinateOperation} and if its properties
+     *       (operation method, source and target CRS) are compatible with the arguments values, then that operation is
+     *       returned as-is.
+     *
+     *       <div class="note"><b>Note:</b> we do not have many objects that are both a {@code CoordinateOperation}
+     *       and a {@code MathTransform}, but that combination is not forbidden. Since such practice is sometime
+     *       convenient for the implementor, Apache SIS allows that.</div></li>
+     *
+     *   <li>If the given {@code type} is null, then this method infers the type from whether the given properties
+     *       specify and accuracy or not. If those properties were created by the {@link #properties(Identifier)}
+     *       method, then the operation will be a {@link Transformation} instance instead of {@link Conversion} if
+     *       the {@code name} identifier was {@link #DATUM_SHIFT} or {@link #ELLIPSOID_CHANGE}.</li>
+     *
+     *   <li>If the given {@code method} is {@code null}, then infer an operation method by inspecting the given transform.
+     *       The transform needs to implement the {@link org.apache.sis.parameter.Parameterized} interface in order to allow
+     *       operation method discovery.</li>
+     *
+     *   <li>Delegate to {@link DefaultCoordinateOperationFactory#createSingleOperation
+     *       DefaultCoordinateOperationFactory.createSingleOperation(…)}.</li>
+     * </ul>
+     *
+     * @param  properties The properties to give to the operation, as a modifiable map.
+     * @param  sourceCRS  The source coordinate reference system.
+     * @param  targetCRS  The destination coordinate reference system.
+     * @param  transform  The math transform.
+     * @param  method     The operation method, or {@code null} if unknown.
+     * @param  parameters The operations parameters, or {@code null} for automatic detection (not always reliable).
+     * @param  type       {@code Conversion.class}, {@code Transformation.class}, or {@code null} if unknown.
+     * @return A coordinate operation using the specified math transform.
+     * @throws FactoryException if the operation can not be created.
+     */
+    final CoordinateOperation createFromMathTransform(final Map<String,Object>        properties,
+                                                      final CoordinateReferenceSystem sourceCRS,
+                                                      final CoordinateReferenceSystem targetCRS,
+                                                      final MathTransform             transform,
+                                                            OperationMethod           method,
+                                                      final ParameterValueGroup       parameters,
+                                                      Class<? extends CoordinateOperation> type)
+            throws FactoryException
+    {
+        /*
+         * If the specified math transform is already a coordinate operation, and if its properties (method,
+         * source and target CRS) are compatible with the specified ones, then that operation is returned as-is.
+         */
+        if (transform instanceof CoordinateOperation) {
+            final CoordinateOperation operation = (CoordinateOperation) transform;
+            if (Objects.equals(operation.getSourceCRS(),     sourceCRS) &&
+                Objects.equals(operation.getTargetCRS(),     targetCRS) &&
+                Objects.equals(operation.getMathTransform(), transform) &&
+                (method == null || !(operation instanceof SingleOperation) ||
+                    Objects.equals(((SingleOperation) operation).getMethod(), method)))
+            {
+                return operation;
+            }
+        }
+        /*
+         * If the operation type was not explicitely specified, infers it from whether an accuracy is specified
+         * or not. In principle, only transformations has an accuracy property; conversions do not. This policy
+         * is applied by the properties(Identifier) method in this class.
+         */
+        if (type == null) {
+            type = properties.containsKey(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY)
+                    ? Transformation.class : Conversion.class;
+        }
+        /*
+         * The operation method is mandatory. If the user did not provided one, we need to infer it ourselves.
+         * If we fail to infer an OperationMethod, let it to null - the exception will be thrown by the factory.
+         */
+        if (method == null) {
+            final Matrix matrix = MathTransforms.getMatrix(transform);
+            if (matrix != null) {
+                method = Affine.getProvider(transform.getSourceDimensions(), transform.getTargetDimensions(), Matrices.isAffine(matrix));
+            } else {
+                final ParameterDescriptorGroup descriptor = AbstractCoordinateOperation.getParameterDescriptors(transform);
+                if (descriptor != null) {
+                    final Identifier name = descriptor.getName();
+                    if (name != null) {
+                        method = factory.getOperationMethod(name.getCode());
+                    }
+                    if (method == null) {
+                        method = factory.createOperationMethod(properties,
+                                sourceCRS.getCoordinateSystem().getDimension(),
+                                targetCRS.getCoordinateSystem().getDimension(),
+                                descriptor);
+                    }
+                }
+            }
+        }
+        if (parameters != null) {
+            properties.put(ReferencingServices.PARAMETERS_KEY, parameters);
+        }
+        properties.put(ReferencingServices.OPERATION_TYPE_KEY, type);
+        if (Conversion.class.isAssignableFrom(type) && transform.isIdentity()) {
+            properties.replace(IdentifiedObject.NAME_KEY, AXIS_CHANGES, IDENTITY);
+        }
+        return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS, null, method, transform);
+    }
+
+    /**
      * Logs an unexpected but ignorable exception. This method pretends that the logging
-     * come from {@link DefaultCoordinateOperationFactory} since this is the public API
-     * which use this {@code CoordinateOperationRegistry} class.
+     * come from {@link CoordinateOperationFinder} since this is the public API which
+     * use this {@code CoordinateOperationRegistry} class.
      *
      * @param exception  the exception which occurred.
      */
-    private void log(final FactoryException exception) {
+    private static void log(final FactoryException exception) {
         final LogRecord record = new LogRecord(Level.WARNING, exception.getLocalizedMessage());
         record.setLoggerName(Loggers.COORDINATE_OPERATION);
-        Logging.log(DefaultCoordinateOperationFactory.class, "createOperation", record);
+        Logging.log(CoordinateOperationFinder.class, "createOperation", record);
     }
 }

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=1738874&r1=1738873&r2=1738874&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] Tue Apr 12 22:23:32 2016
@@ -25,6 +25,7 @@ import org.opengis.util.NoSuchIdentifier
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.*;
+import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.GeographicCRS;
@@ -37,6 +38,7 @@ import org.apache.sis.internal.referenci
 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.internal.util.Constants;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
@@ -88,7 +90,7 @@ public class DefaultCoordinateOperationF
     private final Map<String,?> defaultProperties;
 
     /**
-     * The factory to use if {@link CoordinateOperationInference} needs to create CRS for intermediate steps.
+     * The factory to use if {@link CoordinateOperationFinder} needs to create CRS for intermediate steps.
      * Will be created only when first needed.
      *
      * @see #getCRSFactory()
@@ -96,7 +98,7 @@ public class DefaultCoordinateOperationF
     private volatile CRSFactory crsFactory;
 
     /**
-     * The factory to use if {@link CoordinateOperationInference} needs to create CS for intermediate steps.
+     * The factory to use if {@link CoordinateOperationFinder} needs to create CS for intermediate steps.
      * Will be created only when first needed.
      *
      * @see #getCSFactory()
@@ -183,7 +185,7 @@ public class DefaultCoordinateOperationF
     }
 
     /**
-     * Returns the factory to use if {@link CoordinateOperationInference} needs to create CRS for intermediate steps.
+     * Returns the factory to use if {@link CoordinateOperationFinder} needs to create CRS for intermediate steps.
      */
     final CRSFactory getCRSFactory() {
         CRSFactory factory = crsFactory;
@@ -194,7 +196,7 @@ public class DefaultCoordinateOperationF
     }
 
     /**
-     * Returns the factory to use if {@link CoordinateOperationInference} needs to create CS for intermediate steps.
+     * Returns the factory to use if {@link CoordinateOperationFinder} needs to create CS for intermediate steps.
      */
     final CSFactory getCSFactory() {
         CSFactory factory = csFactory;
@@ -664,14 +666,16 @@ next:   for (int i=components.size(); --
      * widest intersection between its {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of
      * validity} and the {@linkplain CoordinateOperationContext#getAreaOfInterest() area of interest} is returned.
      *
-     * <p>The default implementation is as below:</p>
+     * <p>The default implementation is equivalent to the following code
+     * (omitting the cast safety check for brevity):</p>
      *
      * {@preformat java
-     *   return new CoordinateOperationInference(this, context).createOperation(sourceCRS, targetCRS);
+     *   CoordinateOperationAuthorityFactory registry = (CoordinateOperationAuthorityFactory) CRS.getAuthorityFactory("EPSG");
+     *   return new CoordinateOperationFinder(registry, this, context).createOperation(sourceCRS, targetCRS);
      * }
      *
      * Subclasses can override this method if they need, for example, to use a custom
-     * {@link CoordinateOperationInference} implementation.
+     * {@link CoordinateOperationFinder} implementation.
      *
      * @param  sourceCRS  input coordinate reference system.
      * @param  targetCRS  output coordinate reference system.
@@ -680,7 +684,7 @@ next:   for (int i=components.size(); --
      * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
      * @throws FactoryException if the operation creation failed for some other reason.
      *
-     * @see CoordinateOperationInference
+     * @see CoordinateOperationFinder
      *
      * @since 0.7
      */
@@ -689,7 +693,9 @@ next:   for (int i=components.size(); --
                                                final CoordinateOperationContext context)
             throws OperationNotFoundException, FactoryException
     {
-        return new CoordinateOperationInference(this, context).createOperation(sourceCRS, targetCRS);
+        final AuthorityFactory registry = CRS.getAuthorityFactory(Constants.EPSG);
+        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/SubOperationInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -105,7 +105,7 @@ final class SubOperationInfo {
      * @return information about a coordinate operation from a source CRS to the given target CRS, or {@code null}.
      * @throws FactoryException if an error occurred while grabbing a coordinate operation.
      */
-    static SubOperationInfo create(final CoordinateOperationInference caller, final boolean[] sourceIsUsed,
+    static SubOperationInfo create(final CoordinateOperationFinder caller, final boolean[] sourceIsUsed,
             final List<? extends SingleCRS> sources, final SingleCRS target) throws FactoryException
     {
         OperationNotFoundException failure = null;
@@ -149,7 +149,7 @@ final class SubOperationInfo {
                             sourceIsUsed[i] = true;
                             if (failure != null) {
                                 Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
-                                        CoordinateOperationInference.class, "decompose", failure);
+                                        CoordinateOperationFinder.class, "decompose", failure);
                             }
                             return new SubOperationInfo(operation, startAtDimension, endAtDimension);
                         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java?rev=1738874&r1=1738873&r2=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/package-info.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -86,7 +86,7 @@
  * exists in the form of the {@link org.apache.sis.referencing.datum.DefaultGeodeticDatum#getBursaWolfParameters()}
  * method for those who really need it. This means that when searching for a coordinate operation between a given
  * pair of CRS, Apache SIS will query {@link org.apache.sis.referencing.factory.sql.EPSGFactory} before to try to
- * {@linkplain org.apache.sis.referencing.operation.CoordinateOperationInference infer the operation path by itelf}.
+ * {@linkplain org.apache.sis.referencing.operation.CoordinateOperationFinder infer the operation path by itelf}.
  * The {@link org.apache.sis.referencing.operation.CoordinateOperationContext} can be used for further refinements,
  * for example by specifying the area of interest.
  *

Copied: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java (from r1738873, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java?p2=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java&p1=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java&r1=1738873&r2=1738874&rev=1738874&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] Tue Apr 12 22:23:32 2016
@@ -66,7 +66,7 @@ import static org.apache.sis.test.Assert
 
 
 /**
- * Tests {@link CoordinateOperationInference}.
+ * Tests {@link CoordinateOperationFinder}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
@@ -79,7 +79,7 @@ import static org.apache.sis.test.Assert
     DefaultPassThroughOperationTest.class,
     DefaultConcatenatedOperationTest.class
 })
-public final strictfp class CoordinateOperationInferenceTest extends MathTransformTestCase {
+public final strictfp class CoordinateOperationFinderTest 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:
@@ -103,13 +103,15 @@ public final strictfp class CoordinateOp
     /**
      * The instance on which to execute the tests.
      */
-    private CoordinateOperationInference inference;
+    private CoordinateOperationFinder inference;
 
     /**
      * Creates a new test case.
+     *
+     * @throws FactoryException if an error occurred while initializing the finder to test.
      */
-    public CoordinateOperationInferenceTest() {
-        inference = new CoordinateOperationInference(factory, null);
+    public CoordinateOperationFinderTest() throws FactoryException {
+        inference = new CoordinateOperationFinder(null, factory, null);
     }
 
     /**
@@ -188,7 +190,7 @@ public final strictfp class CoordinateOp
         assertTrue      ("isIdentity", operation.getMathTransform().isIdentity());
         assertTrue      ("accuracy",   operation.getCoordinateOperationAccuracy().isEmpty());
         assertInstanceOf("operation",  Conversion.class, operation);
-        inference = new CoordinateOperationInference(factory, null);        // Reset for next call.
+        inference = new CoordinateOperationFinder(null, factory, null);        // Reset for next call.
     }
 
     /**

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=1738874&r1=1738873&r2=1738874&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] Tue Apr 12 22:23:32 2016
@@ -104,7 +104,7 @@ public final strictfp class CoordinateOp
     public CoordinateOperationRegistryTest() throws FactoryException {
         final CRSAuthorityFactory crsFactory = CRS.getAuthorityFactory("EPSG");
         assumeTrue("EPSG factory required.", crsFactory instanceof CoordinateOperationAuthorityFactory);
-        registry = new CoordinateOperationRegistry(factory, (CoordinateOperationAuthorityFactory) crsFactory, null);
+        registry = new CoordinateOperationRegistry((CoordinateOperationAuthorityFactory) crsFactory, factory, null);
     }
 
     /**

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=1738874&r1=1738873&r2=1738874&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] Tue Apr 12 22:23:32 2016
@@ -217,7 +217,7 @@ 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.CoordinateOperationInferenceTest.class,
+    org.apache.sis.referencing.operation.CoordinateOperationFinderTest.class,
     org.apache.sis.referencing.operation.CoordinateOperationRegistryTest.class,
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
 



Mime
View raw message