sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1740661 - in /sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing: IdentifiedObjects.java factory/IdentifiedObjectFinder.java operation/CoordinateOperationFinder.java operation/CoordinateOperationRegistry.java
Date Sat, 23 Apr 2016 17:25:04 GMT
Author: desruisseaux
Date: Sat Apr 23 17:25:04 2016
New Revision: 1740661

URL: http://svn.apache.org/viewvc?rev=1740661&view=rev
Log:
When creating a new CRS as an intermediate step between the source and target CRS, check if
that CRS is defined by the authority (e.g. EPSG).

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1740661&r1=1740660&r2=1740661&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] Sat Apr 23 17:25:04 2016
@@ -42,6 +42,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
+import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
 
 import static org.apache.sis.internal.util.Citations.iterator;
 import static org.apache.sis.internal.util.Citations.identifierMatches;
@@ -514,14 +515,17 @@ public final class IdentifiedObjects ext
      * @param  authority The authority of the objects to search (typically {@code "EPSG"}
or {@code "OGC"}),
      *         or {@code null} for searching among the objects created by all authorities.
      * @return A finder to use for looking up unidentified objects.
-     * @throws FactoryException if the finder can not be created.
+     * @throws NoSuchAuthorityFactoryException if the given authority is not found.
+     * @throws FactoryException if the finder can not be created for another reason.
      *
      * @see #lookupEPSG(IdentifiedObject)
      * @see #lookupURN(IdentifiedObject, Citation)
      * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#newIdentifiedObjectFinder()
      * @see IdentifiedObjectFinder#find(IdentifiedObject)
      */
-    public static IdentifiedObjectFinder newFinder(final String authority) throws FactoryException
{
+    public static IdentifiedObjectFinder newFinder(final String authority)
+            throws NoSuchAuthorityFactoryException, FactoryException
+    {
         final GeodeticAuthorityFactory factory;
         if (authority == null) {
             factory = AuthorityFactories.ALL;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java?rev=1740661&r1=1740660&r2=1740661&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
[UTF-8] Sat Apr 23 17:25:04 2016
@@ -17,7 +17,6 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Set;
-import java.util.Iterator;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import org.opengis.util.GenericName;
@@ -338,11 +337,16 @@ public class IdentifiedObjectFinder {
 
     /**
      * Lookups only one object which is approximatively equal to the specified object.
-     * If the set returned by {@link #find(IdentifiedObject)} contains exactly one element,
-     * then that element is returned. Otherwise this method returns {@code null}.
+     * This method invokes {@link #find(IdentifiedObject)}, then examine the returned {@code
Set} as below:
      *
-     * <p>This method returns {@code null} if there is more than one element
-     * because in such case we consider that there is an ambiguity.</p>
+     * <ul>
+     *   <li>If the set is empty, then this method returns {@code null}.</li>
+     *   <li>If the set contains exactly one element, then this method returns that
element.</li>
+     *   <li>If the set contains more than one element, but only one element has the
same axis order
+     *       than {@code object} and all other elements have different axis order,
+     *       then this method returns the single element having the same axis order.</li>
+     *   <li>Otherwise this method considers that there is ambiguity and returns {@code
null}.</li>
+     * </ul>
      *
      * @param  object The object looked up.
      * @return The identified object, or {@code null} if none or ambiguous.
@@ -353,18 +357,25 @@ public class IdentifiedObjectFinder {
          * Do not invoke Set.size() because it may be a costly operation if the subclass
          * implements a mechanism that create IdentifiedObject instances only on demand.
          */
+        IdentifiedObject result = null;
+        boolean sameAxisOrder = false;
+        boolean ambiguous = false;
         try {
-            final Iterator<IdentifiedObject> it = find(object).iterator();
-            if (it.hasNext()) {
-                final IdentifiedObject candidate = it.next();
-                if (!it.hasNext()) {
-                    return candidate;
+            for (final IdentifiedObject candidate : find(object)) {
+                final boolean so = !ignoreAxes || Utilities.deepEquals(candidate, object,
COMPARISON_MODE);
+                if (result != null) {
+                    ambiguous = true;
+                    if (sameAxisOrder && so) {
+                        return null;            // Found two matches even when taking in
account axis order.
+                    }
                 }
+                result = candidate;
+                sameAxisOrder = so;
             }
         } catch (BackingStoreException e) {
             throw e.unwrapOrRethrow(FactoryException.class);
         }
-        return null;
+        return (sameAxisOrder || !ambiguous) ? result : null;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1740661&r1=1740660&r2=1740661&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] Sat Apr 23 17:25:04 2016
@@ -579,8 +579,9 @@ public class CoordinateOperationFinder e
         if (!(interpolationCS instanceof EllipsoidalCS)) {
             final EllipsoidalCS cs = CommonCRS.WGS84.geographic3D().getCoordinateSystem();
             if (!equalsIgnoreMetadata(interpolationCS, cs)) {
-                step1 = createOperation(sourceCRS, factorySIS.getCRSFactory()
-                        .createGeographicCRS(derivedFrom(sourceCRS), sourceCRS.getDatum(),
cs));
+                final GeographicCRS stepCRS = factorySIS.getCRSFactory()
+                        .createGeographicCRS(derivedFrom(sourceCRS), sourceCRS.getDatum(),
cs);
+                step1 = createOperation(sourceCRS, toAuthorityDefinition(GeographicCRS.class,
stepCRS));
                 interpolationCRS = step1.getTargetCRS();
                 interpolationCS  = interpolationCRS.getCoordinateSystem();
             }
@@ -609,12 +610,13 @@ public class CoordinateOperationFinder e
             heightCS  = heightCRS.getCoordinateSystem();
             isEllipsoidalHeight = equalsIgnoreMetadata(heightCS.getAxis(0), expectedAxis);
             if (!isEllipsoidalHeight) {
-                heightCS = factorySIS.getCSFactory().createVerticalCS(derivedFrom(heightCS),
expectedAxis);
+                heightCS = toAuthorityDefinition(VerticalCS.class, factorySIS.getCSFactory()
+                        .createVerticalCS(derivedFrom(heightCS), expectedAxis));
             }
         }
         if (!isEllipsoidalHeight) {                     // 'false' if we need to change datum,
unit or axis direction.
-            heightCRS = factorySIS.getCRSFactory()
-                    .createVerticalCRS(derivedFrom(heightCRS), CommonCRS.Vertical.ELLIPSOIDAL.datum(),
heightCS);
+            heightCRS = toAuthorityDefinition(VerticalCRS.class, factorySIS.getCRSFactory()
+                    .createVerticalCRS(derivedFrom(heightCRS), CommonCRS.Vertical.ELLIPSOIDAL.datum(),
heightCS));
         }
         if (heightCRS != targetCRS) {
             step3     = createOperation(heightCRS, targetCRS);  // May need interpolationCRS
for performing datum change.
@@ -781,7 +783,8 @@ public class CoordinateOperationFinder e
             if (stepComponents.length == 1) {
                 stepSourceCRS = stepComponents[0];    // Slight optimization of the next
block (in the 'else' case).
             } else {
-                stepSourceCRS = factorySIS.getCRSFactory().createCompoundCRS(derivedFrom(sourceCRS),
stepComponents);
+                stepSourceCRS = toAuthorityDefinition(CoordinateReferenceSystem.class,
+                        factorySIS.getCRSFactory().createCompoundCRS(derivedFrom(sourceCRS),
stepComponents));
             }
             operation = createFromAffineTransform(AXIS_CHANGES, sourceCRS, stepSourceCRS,
select);
         }
@@ -812,8 +815,8 @@ public class CoordinateOperationFinder e
             } else if (stepComponents.length == 1) {
                 stepTargetCRS = target;                 // Slight optimization of the next
block.
             } else {
-                stepTargetCRS = ReferencingServices.getInstance().createCompoundCRS(
-                        factorySIS.getCRSFactory(), factorySIS.getCSFactory(), derivedFrom(target),
stepComponents);
+                stepTargetCRS = toAuthorityDefinition(CoordinateReferenceSystem.class, ReferencingServices.getInstance()
+                        .createCompoundCRS(factorySIS.getCRSFactory(), factorySIS.getCSFactory(),
derivedFrom(target), stepComponents));
             }
             int delta = source.getCoordinateSystem().getDimension();
             final int startAtDimension = endAtDimension;

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=1740661&r1=1740660&r2=1740661&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] Sat Apr 23 17:25:04 2016
@@ -55,6 +55,7 @@ import org.apache.sis.referencing.factor
 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.referencing.factory.NoSuchAuthorityFactoryException;
 import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
@@ -150,7 +151,8 @@ class CoordinateOperationRegistry {
     }
 
     /**
-     * The object to use for finding authority codes.
+     * The object to use for finding authority codes, or {@code null} if none.
+     * An instance is fetched at construction time from the {@link #registry} if possible.
      */
     private final IdentifiedObjectFinder codeFinder;
 
@@ -212,17 +214,22 @@ class CoordinateOperationRegistry {
         this.factory  = factory;
         factorySIS    = (factory instanceof DefaultCoordinateOperationFactory)
                         ? (DefaultCoordinateOperationFactory) factory : CoordinateOperations.factory();
+        IdentifiedObjectFinder codeFinder = null;
         if (registry != null) {
             if (registry instanceof GeodeticAuthorityFactory) {
                 codeFinder = ((GeodeticAuthorityFactory) registry).newIdentifiedObjectFinder();
-            } else {
+            } else try {
                 codeFinder = IdentifiedObjects.newFinder(Citations.getIdentifier(registry.getAuthority(),
false));
+            } catch (NoSuchAuthorityFactoryException e) {
+                Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
+                        CoordinateOperationRegistry.class, "<init>", e);
+            }
+            if (codeFinder != null) {
+                codeFinder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
+                codeFinder.setIgnoringAxes(true);
             }
-            codeFinder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
-            codeFinder.setIgnoringAxes(true);
-        } else {
-            codeFinder = null;
         }
+        this.codeFinder = codeFinder;
         if (context != null) {
             areaOfInterest  = context.getAreaOfInterest();
             desiredAccuracy = context.getDesiredAccuracy();
@@ -231,12 +238,36 @@ class CoordinateOperationRegistry {
     }
 
     /**
+     * If the authority defines an object equal, ignoring metadata, to the given object,
returns that authority object.
+     * Otherwise returns the given object unchanged. We do not invoke this method for user-supplied
CRS, but only for
+     * CRS or other objects created by {@code CoordinateOperationRegistry} as intermediate
step.
+     */
+    final <T extends IdentifiedObject> T toAuthorityDefinition(final Class<T>
type, final T object) throws FactoryException {
+        if (codeFinder != null) {
+            codeFinder.setIgnoringAxes(false);
+            final IdentifiedObject candidate = codeFinder.findSingleton(object);
+            codeFinder.setIgnoringAxes(true);
+            if (Utilities.equalsIgnoreMetadata(object, candidate)) {
+                return type.cast(candidate);
+            }
+        }
+        return object;
+    }
+
+    /**
      * Finds the authority code for the given coordinate reference system.
      * This method does not trust the code given by the user in its CRS - we verify it.
+     * This method may return a code even if the axis order does not match;
+     * it will be caller's responsibility to make necessary adjustments.
      */
     private String findCode(final CoordinateReferenceSystem crs) throws FactoryException
{
-        final Identifier identifier = IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs),
null);
-        return (identifier != null) ? identifier.getCode() : null;
+        if (codeFinder != null) {
+            final Identifier identifier = IdentifiedObjects.getIdentifier(codeFinder.findSingleton(crs),
null);
+            if (identifier != null) {
+                return identifier.getCode();
+            }
+        }
+        return null;
     }
 
     /**
@@ -403,7 +434,7 @@ class CoordinateOperationRegistry {
                 } catch (NoninvertibleTransformException exception) {
                     // It may be a normal failure - the operation is not required to be invertible.
                     Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
-                            CoordinateOperationRegistry.class, "search", exception);
+                            CoordinateOperationRegistry.class, "createOperation", exception);
                     continue;
                 }
             } catch (MissingFactoryResourceException e) {
@@ -862,10 +893,11 @@ class CoordinateOperationRegistry {
                 return candidate;               // Keep the existing instance since it may
contain useful metadata.
             }
         }
-        return ReferencingServices.getInstance().createCompoundCRS(
-                factorySIS.getCRSFactory(),
-                factorySIS.getCSFactory(),
-                derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs());
+        return toAuthorityDefinition(CoordinateReferenceSystem.class,
+                ReferencingServices.getInstance().createCompoundCRS(
+                        factorySIS.getCRSFactory(),
+                        factorySIS.getCSFactory(),
+                        derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
     }
 
     /**



Mime
View raw message