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()));
}
/**