Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -18,9 +18,9 @@ package org.apache.sis.internal.referenc import javax.measure.unit.SI; import javax.measure.unit.Unit; +import javax.measure.quantity.Length; import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.cs.CartesianCS; -import org.opengis.referencing.cs.CoordinateSystemAxis; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.cs.AxisFilter; import org.apache.sis.referencing.cs.CoordinateSystems; @@ -40,10 +40,10 @@ import static org.opengis.referencing.Id * * @author Martin Desruisseaux (Geomatys) * @since 0.4 - * @version 0.6 + * @version 0.7 * @module */ -public final class Legacy implements AxisFilter { +public final class Legacy { /** * A three-dimensional Cartesian CS with the legacy set of geocentric axes. * OGC 01-009 defines the default geocentric axes as: @@ -62,6 +62,12 @@ public final class Legacy implements Axi new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Z"), "Z", AxisDirection.NORTH, SI.METRE)); /** + * Do not allow instantiation of this class. + */ + private Legacy() { + } + + /** * The standard three-dimensional Cartesian CS as defined by ISO 19111. * * @param unit The linear unit of the desired coordinate system, or {@code null} for metres. @@ -108,71 +114,8 @@ public final class Legacy implements Axi */ public static CartesianCS replaceUnit(CartesianCS cs, final Unit<?> unit) { if (unit != null && !unit.equals(SI.METRE)) { - cs = (CartesianCS) CoordinateSystems.replaceAxes(cs, new Legacy(unit)); + cs = (CartesianCS) CoordinateSystems.replaceLinearUnit(cs, unit.asType(Length.class)); } return cs; } - - - - - // ----------------------------------------------------------------- - // AxisFilter implementation for internal usage only - // ----------------------------------------------------------------- - - /** - * The value to be returned by {@link #getUnitReplacement(CoordinateSystemAxis, Unit)}, - * or {@code null} if no replacement should be done. - */ - private final Unit<?> replacement; - - /** - * For internal usage by {@link #replaceUnit(CartesianCS, Unit)} only. - */ - private Legacy(final Unit<?> unit) { - replacement = unit; - } - - @Override - @Deprecated - public Unit<?> getUnitReplacement(Unit<?> unit) { - return getUnitReplacement(null, unit); - } - - /** - * For internal usage by {@link #replaceUnit(CartesianCS, Unit)} only. - * - * @param axis ignored. - * @param unit ignored. - * @return The unit of the new coordinate system. - */ - @Override - public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, final Unit<?> unit) { - return replacement; - } - - /** - * Returns the given axis unchanged. - */ - @Override - public boolean accept(final CoordinateSystemAxis axis) { - return true; - } - - /** - * Returns the given direction unchanged. - */ - @Override - @Deprecated - public AxisDirection getDirectionReplacement(final AxisDirection direction) { - return direction; - } - - /** - * Returns the given direction unchanged. - */ - @Override - public AxisDirection getDirectionReplacement(CoordinateSystemAxis axis, final AxisDirection direction) { - return direction; - } }
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -67,7 +67,7 @@ public final class PositionalAccuracyCon * * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy() */ - private static final double UNKNOWN_ACCURACY = 3000; + public static final double UNKNOWN_ACCURACY = 3000; /** * Default accuracy of datum shift, if not explicitly provided in the EPSG database. @@ -131,8 +131,8 @@ public final class PositionalAccuracyCon * This method tries each of the following procedures and returns the first successful one: * * <ul> - * <li>If a {@link QuantitativeResult} is found with a linear unit, then this accuracy estimate - * is converted to {@linkplain SI#METRE metres} and returned.</li> + * <li>If at least one {@link QuantitativeResult} is found with a linear unit, then the largest + * accuracy estimate is converted to {@linkplain SI#METRE metres} and returned.</li> * <li>Otherwise, if the operation is a {@link Conversion}, then returns 0 since a conversion * is by definition accurate up to rounding errors.</li> * <li>Otherwise, if the operation is a {@link Transformation}, then checks if the datum shift @@ -152,9 +152,10 @@ public final class PositionalAccuracyCon * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy() */ public static double getLinearAccuracy(final CoordinateOperation operation) { + double accuracy = Double.NaN; final Collection<PositionalAccuracy> accuracies = operation.getCoordinateOperationAccuracy(); - for (final PositionalAccuracy accuracy : accuracies) { - for (final Result result : accuracy.getResults()) { + for (final PositionalAccuracy metadata : accuracies) { + for (final Result result : metadata.getResults()) { if (result instanceof QuantitativeResult) { final QuantitativeResult quantity = (QuantitativeResult) result; final Collection<? extends Record> records = quantity.getValues(); @@ -167,7 +168,9 @@ public final class PositionalAccuracyCon if (value instanceof Number) { double v = ((Number) value).doubleValue(); v = unitOfLength.getConverterTo(SI.METRE).convert(v); - return v; + if (v >= 0 && !(v <= accuracy)) { // '!' is for replacing the NaN value. + accuracy = v; + } } } } @@ -176,40 +179,41 @@ public final class PositionalAccuracyCon } } } - /* - * No quantitative (linear) accuracy were found. If the coordinate operation is actually - * a conversion, the accuracy is up to rounding error (i.e. conceptually 0) by definition. - */ - if (operation instanceof Conversion) { - return 0; - } - /* - * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters - * were available for the datum shift. This is SIS-specific. See field javadoc for a rational - * about the return values chosen. - */ - if (operation instanceof Transformation) { - if (accuracies.contains(DATUM_SHIFT_APPLIED)) { - return DATUM_SHIFT_ACCURACY; + if (Double.isNaN(accuracy)) { + /* + * No quantitative (linear) accuracy were found. If the coordinate operation is actually + * a conversion, the accuracy is up to rounding error (i.e. conceptually 0) by definition. + */ + if (operation instanceof Conversion) { + return 0; } - if (accuracies.contains(DATUM_SHIFT_OMITTED)) { - return UNKNOWN_ACCURACY; + /* + * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters + * were available for the datum shift. This is SIS-specific. See field javadoc for a rational + * about the return values chosen. + */ + if (operation instanceof Transformation) { + if (accuracies.contains(DATUM_SHIFT_APPLIED)) { + return DATUM_SHIFT_ACCURACY; + } + if (accuracies.contains(DATUM_SHIFT_OMITTED)) { + return UNKNOWN_ACCURACY; + } } - } - /* - * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy, - * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario, - * since it could be worst if the transforms are highly non-linear). - */ - double accuracy = Double.NaN; - if (operation instanceof ConcatenatedOperation) { - for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) { - final double candidate = Math.abs(getLinearAccuracy(op)); - if (!Double.isNaN(candidate)) { - if (Double.isNaN(accuracy)) { - accuracy = candidate; - } else { - accuracy += candidate; + /* + * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy, + * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario, + * since it could be worst if the transforms are highly non-linear). + */ + if (operation instanceof ConcatenatedOperation) { + for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) { + final double candidate = Math.abs(getLinearAccuracy(op)); + if (!Double.isNaN(candidate)) { + if (Double.isNaN(accuracy)) { + accuracy = candidate; + } else { + accuracy += candidate; + } } } } Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -247,9 +247,16 @@ public final class ReferencingUtilities /** * Returns the properties of the given object but potentially with a modified name. * Current implement truncates the name at the first non-white character which is not - * a valid Unicode identifier part. + * a valid Unicode identifier part, with the following exception: + * + * <ul> + * <li>If the character is {@code '('} and the content until the closing {@code ')'} is a valid + * Unicode identifier, then that part is included. The intend is to keep the prime meridian + * name in names like <cite>"NTF (Paris)"</cite>.</li> + * </ul> * * <div class="note"><b>Example:</b><ul> + * <li><cite>"NTF (Paris)"</cite> is left unchanged.</li> * <li><cite>"WGS 84 (3D)"</cite> is truncated as <cite>"WGS 84"</cite>.</li> * <li><cite>"Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: degree"</cite> * is truncated as <cite>"Ellipsoidal 2D CS"</cite>.</li> @@ -272,6 +279,15 @@ public final class ReferencingUtilities for (int i=0; i < name.length();) { final int c = name.codePointAt(i); if (!Character.isUnicodeIdentifierPart(c) && !Character.isSpaceChar(c)) { + if (c == '(') { + final int endAt = name.indexOf(')', i); + if (endAt >= 0) { + final String extra = name.substring(i+1, endAt); + if (CharSequences.isUnicodeIdentifier(extra)) { + i += extra.length() + 2; + } + } + } name = CharSequences.trimWhitespaces(name, 0, i).toString(); if (!name.isEmpty()) { final Map<String,Object> copy = new HashMap<String,Object>(properties); Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -17,8 +17,10 @@ package org.apache.sis.internal.referencing; import java.util.Map; +import java.util.HashMap; import java.util.Iterator; import java.util.Collection; +import java.util.Collections; import java.util.Locale; import javax.measure.unit.Unit; import javax.measure.quantity.Length; @@ -34,6 +36,9 @@ import org.opengis.referencing.crs.Tempo import org.opengis.referencing.crs.VerticalCRS; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.CRSFactory; +import org.opengis.referencing.cs.CSFactory; +import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.cs.CartesianCS; import org.opengis.referencing.cs.CoordinateSystem; import org.opengis.referencing.cs.CoordinateSystemAxis; @@ -54,7 +59,6 @@ import org.opengis.metadata.extent.Geogr import org.opengis.metadata.extent.VerticalExtent; import org.opengis.geometry.Envelope; -import org.opengis.referencing.cs.AxisDirection; import org.apache.sis.geometry.Envelopes; import org.apache.sis.referencing.CRS; import org.apache.sis.referencing.CommonCRS; @@ -88,6 +92,9 @@ import org.apache.sis.util.resources.Err import org.apache.sis.util.Exceptions; import org.apache.sis.util.Utilities; +// Branch-dependent imports +import org.apache.sis.internal.jdk8.JDK8; + /** * Implements the referencing services needed by the {@code "sis-metadata"} module. @@ -151,7 +158,7 @@ public final class ServicesForMetadata e !Utilities.equalsIgnoreMetadata(cs2.getAxis(1), cs1.getAxis(1))) { final CoordinateOperation operation; - final CoordinateOperationFactory factory = DefaultFactories.forBuildin(CoordinateOperationFactory.class); + final CoordinateOperationFactory factory = CoordinateOperations.factory(); try { operation = factory.createOperation(crs, normalizedCRS); } catch (FactoryException e) { @@ -611,7 +618,7 @@ public final class ServicesForMetadata e if (factory instanceof DefaultCoordinateOperationFactory) { df = (DefaultCoordinateOperationFactory) factory; } else { - df = DefaultFactories.forBuildin(CoordinateOperationFactory.class, DefaultCoordinateOperationFactory.class); + df = CoordinateOperations.factory(); } return df.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, null); } @@ -623,17 +630,30 @@ public final class ServicesForMetadata e * * @param properties The default properties. * @param mtFactory The math transform factory to use. + * @param crsFactory The factory to use if the operation factory needs to create CRS for intermediate steps. + * @param csFactory The factory to use if the operation factory needs to create CS for intermediate steps. * @return The coordinate operation factory to use. * - * @since 0.6 + * @since 0.7 */ @Override - public CoordinateOperationFactory getCoordinateOperationFactory(Map<String,?> properties, MathTransformFactory mtFactory) { - if (Containers.isNullOrEmpty(properties) && DefaultFactories.isDefaultInstance(MathTransformFactory.class, mtFactory)) { - return DefaultFactories.forBuildin(CoordinateOperationFactory.class); - } else { - return new DefaultCoordinateOperationFactory(properties, mtFactory); + public CoordinateOperationFactory getCoordinateOperationFactory(Map<String,?> properties, + final MathTransformFactory mtFactory, final CRSFactory crsFactory, final CSFactory csFactory) + { + if (Containers.isNullOrEmpty(properties)) { + if (DefaultFactories.isDefaultInstance(MathTransformFactory.class, mtFactory) && + DefaultFactories.isDefaultInstance(CRSFactory.class, crsFactory) && + DefaultFactories.isDefaultInstance(CSFactory.class, csFactory)) + { + return CoordinateOperations.factory(); + } + properties = Collections.emptyMap(); } + final HashMap<String,Object> p = new HashMap<String,Object>(properties); + JDK8.putIfAbsent(p, CRS_FACTORY, crsFactory); + JDK8.putIfAbsent(p, CS_FACTORY, csFactory); + properties = p; + return new DefaultCoordinateOperationFactory(properties, mtFactory); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbridgedMolodensky.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -22,10 +22,8 @@ import org.opengis.parameter.ParameterVa import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.OperationMethod; import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.parameter.Parameters; -import org.apache.sis.util.ArgumentChecks; /** @@ -70,22 +68,11 @@ public final class AbridgedMolodensky ex } /** - * The providers for all combinations between 2D and 3D cases. - * Array length is 4. Index is build with following rule: - * <ul> - * <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li> - * <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li> - * </ul> - */ - private final AbridgedMolodensky[] redimensioned; - - /** * Constructs a new provider. */ @SuppressWarnings("ThisEscapedInObjectConstruction") public AbridgedMolodensky() { - super(3, 3, PARAMETERS); - redimensioned = new AbridgedMolodensky[4]; + this(3, 3, new AbridgedMolodensky[4]); redimensioned[0] = new AbridgedMolodensky(2, 2, redimensioned); redimensioned[1] = new AbridgedMolodensky(2, 3, redimensioned); redimensioned[2] = new AbridgedMolodensky(3, 2, redimensioned); @@ -95,27 +82,12 @@ public final class AbridgedMolodensky ex /** * Constructs a provider for the given dimensions. * - * @param sourceDimension Number of dimensions in the source CRS of this operation method. - * @param targetDimension Number of dimensions in the target CRS of this operation method. - * @param redimensioned Providers for all combinations between 2D and 3D cases. - */ - private AbridgedMolodensky(final int sourceDimension, final int targetDimension, final AbridgedMolodensky[] redimensioned) { - super(sourceDimension, targetDimension, PARAMETERS); - this.redimensioned = redimensioned; - } - - /** - * Returns the same operation method, but for different number of dimensions. - * - * @param sourceDimensions The desired number of input dimensions. - * @param targetDimensions The desired number of output dimensions. - * @return The redimensioned operation method, or {@code this} if no change is needed. + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. */ - @Override - public OperationMethod redimension(final int sourceDimensions, final int targetDimensions) { - ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions); - ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions); - return redimensioned[((sourceDimensions & 1) << 1) | (targetDimensions & 1)]; + private AbridgedMolodensky(int sourceDimension, int targetDimension, GeodeticOperation[] redimensioned) { + super(sourceDimension, targetDimension, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -76,15 +76,15 @@ public abstract class AbstractProvider e * Constructs a math transform provider from a set of parameters. The provider name and * {@linkplain #getIdentifiers() identifiers} will be the same than the parameter ones. * - * @param sourceDimension Number of dimensions in the source CRS of this operation method. - * @param targetDimension Number of dimensions in the target CRS of this operation method. - * @param parameters The set of parameters (never {@code null}). + * @param sourceDimensions Number of dimensions in the source CRS of this operation method. + * @param targetDimensions Number of dimensions in the target CRS of this operation method. + * @param parameters Description of parameters expected by this operation. */ - AbstractProvider(final int sourceDimension, - final int targetDimension, + AbstractProvider(final int sourceDimensions, + final int targetDimensions, final ParameterDescriptorGroup parameters) { - super(toMap(parameters), sourceDimension, targetDimension, parameters); + super(toMap(parameters), sourceDimensions, targetDimensions, parameters); } /** @@ -180,7 +180,7 @@ public abstract class AbstractProvider e } /** - * Creates a false easting or northing parameter in metre with a default value of 0. + * Creates a false easting, false northing or height parameter in metre with a default value of 0. */ static ParameterDescriptor<Double> createShift(final ParameterBuilder builder) { return builder.create(0.0, SI.METRE); @@ -219,7 +219,24 @@ public abstract class AbstractProvider e * Returns {@code true} if the inverse of this operation method is the same operation method with some parameter * values changed (typically with sign inverted). The default implementation returns {@code false}. * + * <p>This is a SIS-specific information which may be changed in any future SIS version. + * Current implementation provides this information in a "all or nothing" way: either all parameter values + * can have their sign reversed, or either the operation is considered not revertible at all. + * This is different than the EPSG dataset in two way:</p> + * + * <ul class="verbose"> + * <li>EPSG provides an equivalent information in the {@code PARAM_SIGN_REVERSAL} column of the + * {@code [Coordinate_Operation Parameter Usage]} table, but on a parameter-by-parameter basis + * instead than for the whole operation (which is probably better).</li> + * + * <li>EPSG provides another information in the {@code REVERSE_OP} column of the + * {@code [Coordinate_Operation Method]} table, but this is not equivalent to this method because it + * does not differentiate the map projection methods from <em>inverse</em> map projection methods.</li> + * </ul> + * * @return {@code true} if the inverse of this operation method can be described by the same operation method. + * + * @see org.apache.sis.internal.referencing.SignReversalComment */ public boolean isInvertible() { return false; Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Affine.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -236,10 +236,10 @@ public final class Affine extends Abstra * Returns the operation method for the specified source and target dimensions. * This method provides different {@code Affine} instances for different dimensions. * - * @param sourceDimensions The number of source dimensions. - * @param targetDimensions The number of target dimensions. - * @param isAffine {@code true} if the transform is affine. - * @return The provider for transforms of the given source and target dimensions. + * @param sourceDimensions the number of source dimensions. + * @param targetDimensions the number of target dimensions. + * @param isAffine {@code true} if the transform is affine. + * @return the provider for transforms of the given source and target dimensions. */ public static Affine getProvider(final int sourceDimensions, final int targetDimensions, final boolean isAffine) { Affine method; Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -57,7 +57,7 @@ public final class CoordinateFrameRotati * Constructs the provider. */ public CoordinateFrameRotation() { - super(3, 3, PARAMETERS); + super(3, 3, PARAMETERS, null); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -57,7 +57,22 @@ public final class CoordinateFrameRotati * Constructs the provider. */ public CoordinateFrameRotation2D() { - super(2, 2, PARAMETERS); + this(null); + } + + /** + * Constructs a provider that can be resized. + */ + CoordinateFrameRotation2D(GeodeticOperation[] redimensioned) { + super(2, 2, PARAMETERS, redimensioned); + } + + /** + * Returns the three-dimensional variant of this operation method. + */ + @Override + Class<CoordinateFrameRotation3D> variant3D() { + return CoordinateFrameRotation3D.class; } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation3D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -56,8 +56,24 @@ public final class CoordinateFrameRotati /** * Constructs the provider. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") public CoordinateFrameRotation3D() { - super(3, 3, PARAMETERS); + this(3, 3, new GeocentricAffineBetweenGeographic[4]); + redimensioned[0] = new CoordinateFrameRotation2D( redimensioned); + redimensioned[1] = new CoordinateFrameRotation3D(2, 3, redimensioned); + redimensioned[2] = new CoordinateFrameRotation3D(3, 2, redimensioned); + redimensioned[3] = this; + } + + /** + * Constructs a provider for the given dimensions. + * + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. + */ + private CoordinateFrameRotation3D(int sourceDimensions, int targetDimensions, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -38,8 +38,6 @@ import org.opengis.parameter.InvalidPara import org.opengis.referencing.datum.Ellipsoid; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.Transformation; -import org.opengis.referencing.operation.OperationMethod; import org.opengis.referencing.operation.NoninvertibleTransformException; import org.opengis.util.FactoryException; import org.apache.sis.internal.system.Loggers; @@ -47,7 +45,6 @@ import org.apache.sis.internal.system.Da import org.apache.sis.internal.referencing.NilReferencingObject; import org.apache.sis.parameter.ParameterBuilder; import org.apache.sis.parameter.Parameters; -import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.CharSequences; import org.apache.sis.util.logging.Logging; import org.apache.sis.util.resources.Errors; @@ -93,7 +90,7 @@ import org.apache.sis.internal.jdk8.JDK8 * @module */ @XmlTransient -public class FranceGeocentricInterpolation extends AbstractProvider { +public class FranceGeocentricInterpolation extends GeodeticOperation { /** * Serial number for inter-operability with different versions. */ @@ -172,18 +169,6 @@ public class FranceGeocentricInterpolati } /** - * The providers for all combinations between 2D and 3D cases. - * Array length is 4. Index is built with following rule: - * <ul> - * <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li> - * <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li> - * </ul> - * - * This array is initialized at construction time and shall not be modified after. - */ - final FranceGeocentricInterpolation[] redimensioned; - - /** * Constructs a provider. */ @SuppressWarnings("ThisEscapedInObjectConstruction") @@ -198,32 +183,17 @@ public class FranceGeocentricInterpolati /** * Constructs a provider for the given number of dimensions. * - * @param sourceDimensions Number of dimensions in the source CRS of this operation method. - * @param targetDimensions Number of dimensions in the target CRS of this operation method. - * @param parameters The set of parameters (never {@code null}). - * @param redimensioned Providers for all combinations between 2D and 3D cases. + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param parameters description of parameters expected by this operation. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. */ FranceGeocentricInterpolation(final int sourceDimensions, final int targetDimensions, final ParameterDescriptorGroup parameters, - final FranceGeocentricInterpolation[] redimensioned) + final GeodeticOperation[] redimensioned) { - super(sourceDimensions, targetDimensions, parameters); - this.redimensioned = redimensioned; - } - - /** - * Returns the same operation method, but for different number of dimensions. - * - * @param sourceDimensions The desired number of input dimensions. - * @param targetDimensions The desired number of output dimensions. - * @return The redimensioned operation method, or {@code this} if no change is needed. - */ - @Override - public OperationMethod redimension(final int sourceDimensions, final int targetDimensions) { - ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions); - ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions); - return redimensioned[((sourceDimensions & 1) << 1) | (targetDimensions & 1)]; + super(sourceDimensions, targetDimensions, parameters, redimensioned); } /** @@ -240,13 +210,13 @@ public class FranceGeocentricInterpolati } /** - * Returns the base interface of the {@code CoordinateOperation} instances that use this method. + * The inverse of {@code FranceGeocentricInterpolation} is a different operation. * - * @return Fixed to {@link Transformation}. + * @return {@code false}. */ @Override - public Class<Transformation> getOperationType() { - return Transformation.class; + public final boolean isInvertible() { + return false; } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -30,7 +30,6 @@ import org.opengis.referencing.cs.Coordi import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.Transformation; import org.apache.sis.internal.referencing.Formulas; import org.apache.sis.internal.referencing.WKTUtilities; import org.apache.sis.internal.metadata.WKTKeywords; @@ -64,7 +63,7 @@ import org.apache.sis.util.logging.Loggi * @module */ @XmlTransient -public abstract class GeocentricAffine extends AbstractProvider { +public abstract class GeocentricAffine extends GeodeticOperation { /** * Serial number for inter-operability with different versions. */ @@ -153,21 +152,13 @@ public abstract class GeocentricAffine e /** * Constructs a provider with the specified parameters. * - * @param sourceDimensions Number of dimensions in the source CRS of this operation method. - * @param targetDimensions Number of dimensions in the target CRS of this operation method. + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param parameters description of parameters expected by this operation. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. */ - GeocentricAffine(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup parameters) { - super(sourceDimensions, targetDimensions, parameters); - } - - /** - * Returns the interface implemented by all coordinate operations that extends this class. - * - * @return Fixed to {@link Transformation}. - */ - @Override - public final Class<Transformation> getOperationType() { - return Transformation.class; + GeocentricAffine(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup parameters, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, parameters, redimensioned); } /** @@ -177,16 +168,6 @@ public abstract class GeocentricAffine e abstract int getType(); /** - * The inverse of this operation is the same operation with parameter signs inverted. - * - * @return {@code true} for all {@code GeocentricAffine}. - */ - @Override - public final boolean isInvertible() { - return true; - } - - /** * Creates a math transform from the specified group of parameter values. * The default implementation creates an affine transform, but some subclasses * will wrap that affine operation into Geographic/Geocentric conversions. @@ -206,12 +187,12 @@ public abstract class GeocentricAffine e boolean reverseRotation = false; switch (getType()) { default: throw new AssertionError(); - case FRAME_ROTATION: reverseRotation = true; // Fall through + case FRAME_ROTATION: reverseRotation = true; // Fall through case SEVEN_PARAM: parameters.rX = pv.doubleValue(RX); parameters.rY = pv.doubleValue(RY); parameters.rZ = pv.doubleValue(RZ); parameters.dS = pv.doubleValue(DS); - case TRANSLATION: parameters.tX = pv.doubleValue(TX); // Fall through + case TRANSLATION: parameters.tX = pv.doubleValue(TX); // Fall through parameters.tY = pv.doubleValue(TY); parameters.tZ = pv.doubleValue(TZ); } @@ -275,7 +256,7 @@ public abstract class GeocentricAffine e @SuppressWarnings("null") int dimension = sourceCS.getDimension(); if (dimension != targetCS.getDimension()) { - dimension = 0; // Sentinal value for mismatched dimensions. + dimension = 4; // Any value greater than 3 means "mismatched dimensions" for this method. } /* * Try to convert the matrix into (tX, tY, tZ, rX, rY, rZ, dS) parameters. @@ -312,7 +293,7 @@ public abstract class GeocentricAffine e } } final Parameters values = createParameters(descriptor, parameters, isTranslation); - if (useMolodensky && dimension != 0) { + if (useMolodensky && dimension <= 3) { values.getOrCreate(Molodensky.DIMENSION).setValue(dimension); } return values; Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffineBetweenGeographic.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -101,11 +101,15 @@ public abstract class GeocentricAffineBe /** * Constructs a provider with the specified parameters. * - * @param sourceDimensions Number of dimensions in the source CRS of this operation method. - * @param targetDimensions Number of dimensions in the target CRS of this operation method. + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param parameters description of parameters expected by this operation. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. */ - GeocentricAffineBetweenGeographic(int sourceDimensions, int targetDimensions, ParameterDescriptorGroup parameters) { - super(sourceDimensions, targetDimensions, parameters); + GeocentricAffineBetweenGeographic(int sourceDimensions, int targetDimensions, + ParameterDescriptorGroup parameters, GeodeticOperation[] redimensioned) + { + super(sourceDimensions, targetDimensions, parameters, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -52,7 +52,7 @@ public final class GeocentricTranslation * Constructs the provider. */ public GeocentricTranslation() { - super(3, 3, PARAMETERS); + super(3, 3, PARAMETERS, null); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -56,7 +56,22 @@ public final class GeocentricTranslation * Constructs the provider. */ public GeocentricTranslation2D() { - super(2, 2, PARAMETERS); + this(null); + } + + /** + * Constructs a provider that can be resized. + */ + GeocentricTranslation2D(GeodeticOperation[] redimensioned) { + super(2, 2, PARAMETERS, redimensioned); + } + + /** + * Returns the three-dimensional variant of this operation method. + */ + @Override + Class<GeocentricTranslation3D> variant3D() { + return GeocentricTranslation3D.class; } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation3D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -51,8 +51,24 @@ public final class GeocentricTranslation /** * Constructs the provider. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") public GeocentricTranslation3D() { - super(3, 3, PARAMETERS); + this(3, 3, new GeocentricAffineBetweenGeographic[4]); + redimensioned[0] = new GeocentricTranslation2D( redimensioned); + redimensioned[1] = new GeocentricTranslation3D(2, 3, redimensioned); + redimensioned[2] = new GeocentricTranslation3D(3, 2, redimensioned); + redimensioned[3] = this; + } + + /** + * Constructs a provider for the given dimensions. + * + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. + */ + private GeocentricTranslation3D(int sourceDimensions, int targetDimensions, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -37,7 +37,7 @@ import org.apache.sis.internal.referenci /** * The provider for <cite>"Geographic 3D to 2D conversion"</cite> (EPSG:9659). * This is a trivial operation that just drop the height in a geographic coordinate. - * The inverse operation arbitrarily set the ellipsoidal height to zero. + * The inverse operation arbitrarily sets the ellipsoidal height to zero. * * @author Martin Desruisseaux (Geomatys) * @since 0.7 @@ -54,7 +54,7 @@ public final class Geographic3Dto2D exte /** * The group of all parameters expected by this coordinate operation (in this case, none). */ - static final ParameterDescriptorGroup PARAMETERS = builder() + public static final ParameterDescriptorGroup PARAMETERS = builder() .addIdentifier("9659").addName("Geographic3D to 2D conversion").createGroup(); /** @@ -113,9 +113,9 @@ public final class Geographic3Dto2D exte } /** - * A temporary placeholder used for formatting a {@code PARAM_MT["Geographic 3D to 2D conversion"]} - * element in Well-Known Text format. This placeholder is needed there is no {@link MathTransform} - * implementation for the Geographic 3D to 2D conversion, since we use affine transform instead. + * A temporary placeholder used for formatting a {@code PARAM_MT["Geographic 3D to 2D conversion"]} element in + * Well-Known Text format. This placeholder is needed because there is no {@link MathTransform} implementation + * for the Geographic 3D to 2D conversion, since we use affine transform instead. */ public static final class WKT extends FormattableObject implements Parameterized { /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -25,7 +25,6 @@ import org.opengis.parameter.ParameterDe import org.opengis.parameter.ParameterNotFoundException; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.Transformation; import org.apache.sis.parameter.ParameterBuilder; import org.apache.sis.parameter.Parameters; import org.apache.sis.referencing.operation.matrix.Matrix4; @@ -43,7 +42,7 @@ import org.apache.sis.referencing.operat * @module */ @XmlTransient -public class GeographicOffsets extends AbstractProvider { +public class GeographicOffsets extends GeodeticOperation { /** * Serial number for inter-operability with different versions. */ @@ -79,35 +78,22 @@ public class GeographicOffsets extends A /** * Constructs a provider with default parameters. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") public GeographicOffsets() { - super(3, 3, PARAMETERS); + super(3, 3, PARAMETERS, new GeographicOffsets[4]); + redimensioned[0] = new GeographicOffsets2D(redimensioned); + redimensioned[1] = new GeographicOffsets(2, 3, PARAMETERS, redimensioned); + redimensioned[2] = new GeographicOffsets(3, 2, PARAMETERS, redimensioned); + redimensioned[3] = this; } /** * For subclasses constructor only. */ - GeographicOffsets(int dim, ParameterDescriptorGroup parameters) { - super(dim, dim, parameters); - } - - /** - * Returns the operation type. - * - * @return Interface implemented by all coordinate operations that use this method. - */ - @Override - public final Class<Transformation> getOperationType() { - return Transformation.class; - } - - /** - * The inverse of this operation is the same operation with parameter signs inverted. - * - * @return {@code true} for all {@code GeocentricAffine}. - */ - @Override - public final boolean isInvertible() { - return true; + GeographicOffsets(int sourceDimensions, int targetDimensions, + ParameterDescriptorGroup parameters, GeodeticOperation[] redimensioned) + { + super(sourceDimensions, targetDimensions, parameters, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets2D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets2D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets2D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets2D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -53,7 +53,22 @@ public final class GeographicOffsets2D e * Constructs a provider with default parameters. */ public GeographicOffsets2D() { - super(2, PARAMETERS); + this(null); + } + + /** + * Constructs a provider that can be resized. + */ + GeographicOffsets2D(GeodeticOperation[] redimensioned) { + super(2, 2, PARAMETERS, redimensioned); + } + + /** + * Returns the three-dimensional variant of this operation method. + */ + @Override + Class<GeographicOffsets> variant3D() { + return GeographicOffsets.class; } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -65,8 +65,24 @@ public final class LongitudeRotation ext /** * Constructs a provider with default parameters. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") public LongitudeRotation() { - super(2, PARAMETERS); + this(2, 2, new LongitudeRotation[4]); + redimensioned[0] = this; + redimensioned[1] = new LongitudeRotation(2, 3, redimensioned); + redimensioned[2] = new LongitudeRotation(3, 2, redimensioned); + redimensioned[3] = new LongitudeRotation(3, 3, redimensioned); + } + + /** + * Constructs a provider for the given dimensions. + * + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases. + */ + private LongitudeRotation(int sourceDimensions, int targetDimensions, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -29,7 +29,6 @@ import org.opengis.parameter.ParameterNo import org.opengis.parameter.InvalidParameterValueException; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.OperationMethod; import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.parameter.ParameterBuilder; import org.apache.sis.parameter.Parameters; @@ -39,7 +38,6 @@ import org.apache.sis.internal.referenci import org.apache.sis.internal.referencing.Formulas; import org.apache.sis.internal.util.Constants; import org.apache.sis.util.resources.Errors; -import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.Debug; @@ -134,22 +132,11 @@ public final class Molodensky extends Ge } /** - * The providers for all combinations between 2D and 3D cases. - * Array length is 4. Index is built with following rule: - * <ul> - * <li>Bit 1: dimension of source coordinates (0 for 2D, 1 for 3D).</li> - * <li>Bit 0: dimension of target coordinates (0 for 2D, 1 for 3D).</li> - * </ul> - */ - private final Molodensky[] redimensioned; - - /** * Constructs a new provider. */ @SuppressWarnings("ThisEscapedInObjectConstruction") public Molodensky() { - super(3, 3, PARAMETERS); - redimensioned = new Molodensky[4]; + this(3, 3, new Molodensky[4]); redimensioned[0] = new Molodensky(2, 2, redimensioned); redimensioned[1] = new Molodensky(2, 3, redimensioned); redimensioned[2] = new Molodensky(3, 2, redimensioned); @@ -159,27 +146,12 @@ public final class Molodensky extends Ge /** * Constructs a provider for the given dimensions. * - * @param sourceDimensions Number of dimensions in the source CRS of this operation method. - * @param targetDimensions Number of dimensions in the target CRS of this operation method. - * @param redimensioned Providers for all combinations between 2D and 3D cases. - */ - private Molodensky(final int sourceDimensions, final int targetDimensions, final Molodensky[] redimensioned) { - super(sourceDimensions, targetDimensions, PARAMETERS); - this.redimensioned = redimensioned; - } - - /** - * Returns the same operation method, but for different number of dimensions. - * - * @param sourceDimensions The desired number of input dimensions. - * @param targetDimensions The desired number of output dimensions. - * @return The redimensioned operation method, or {@code this} if no change is needed. - */ - @Override - public OperationMethod redimension(final int sourceDimensions, final int targetDimensions) { - ArgumentChecks.ensureBetween("sourceDimensions", 2, 3, sourceDimensions); - ArgumentChecks.ensureBetween("targetDimensions", 2, 3, targetDimensions); - return redimensioned[((sourceDimensions & 1) << 1) | (targetDimensions & 1)]; + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases. + */ + private Molodensky(int sourceDimensions, int targetDimensions, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MolodenskyInterpolation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MolodenskyInterpolation.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MolodenskyInterpolation.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MolodenskyInterpolation.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -68,15 +68,15 @@ public final class MolodenskyInterpolati /** * Constructs a provider for the given number of dimensions. * - * @param sourceDimensions Number of dimensions in the source CRS of this operation method. - * @param targetDimensions Number of dimensions in the target CRS of this operation method. - * @param parameters The set of parameters (never {@code null}). - * @param redimensioned Providers for all combinations between 2D and 3D cases. + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param parameters description of parameters expected by this operation. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. */ private MolodenskyInterpolation(final int sourceDimensions, final int targetDimensions, final ParameterDescriptorGroup parameters, - final FranceGeocentricInterpolation[] redimensioned) + final GeodeticOperation[] redimensioned) { super(sourceDimensions, targetDimensions, parameters, redimensioned); } Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -56,7 +56,7 @@ public final class PositionVector7Param * Constructs the provider. */ public PositionVector7Param() { - super(3, 3, PARAMETERS); + super(3, 3, PARAMETERS, null); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -59,7 +59,22 @@ public final class PositionVector7Param2 * Constructs the provider. */ public PositionVector7Param2D() { - super(2, 2, PARAMETERS); + this(null); + } + + /** + * Constructs a provider that can be resized. + */ + PositionVector7Param2D(GeodeticOperation[] redimensioned) { + super(2, 2, PARAMETERS, redimensioned); + } + + /** + * Returns the three-dimensional variant of this operation method. + */ + @Override + Class<PositionVector7Param3D> variant3D() { + return PositionVector7Param3D.class; } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param3D.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -54,8 +54,24 @@ public final class PositionVector7Param3 /** * Constructs the provider. */ + @SuppressWarnings("ThisEscapedInObjectConstruction") public PositionVector7Param3D() { - super(3, 3, PARAMETERS); + this(3, 3, new GeocentricAffineBetweenGeographic[4]); + redimensioned[0] = new PositionVector7Param2D( redimensioned); + redimensioned[1] = new PositionVector7Param3D(2, 3, redimensioned); + redimensioned[2] = new PositionVector7Param3D(3, 2, redimensioned); + redimensioned[3] = this; + } + + /** + * Constructs a provider for the given dimensions. + * + * @param sourceDimensions number of dimensions in the source CRS of this operation method. + * @param targetDimensions number of dimensions in the target CRS of this operation method. + * @param redimensioned providers for all combinations between 2D and 3D cases, or {@code null}. + */ + private PositionVector7Param3D(int sourceDimensions, int targetDimensions, GeodeticOperation[] redimensioned) { + super(sourceDimensions, targetDimensions, PARAMETERS, redimensioned); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/VerticalOffset.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/VerticalOffset.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/VerticalOffset.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/VerticalOffset.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -70,7 +70,7 @@ public final class VerticalOffset extend * Constructs a provider with default parameters. */ public VerticalOffset() { - super(1, PARAMETERS); + super(1, 1, PARAMETERS, null); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterDescriptorGroup.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -210,8 +210,9 @@ public class DefaultParameterDescriptorG */ private static void verifyNames(final Map<String,?> properties, final GeneralParameterDescriptor[] parameters) { for (int i=0; i<parameters.length; i++) { - ArgumentChecks.ensureNonNullElement("parameters", i, parameters); - final String name = parameters[i].getName().getCode(); + final GeneralParameterDescriptor parameter = parameters[i]; + ArgumentChecks.ensureNonNullElement("parameters", i, parameter); + final String name = parameter.getName().getCode(); for (int j=0; j<i; j++) { if (IdentifiedObjects.isHeuristicMatchForName(parameters[j], name)) { throw new InvalidParameterNameException(Errors.getResources(properties).getString( Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -393,7 +393,7 @@ public class AbstractIdentifiedObject ex final Map<String,?> properties, final String key, final Object value) { return new IllegalArgumentException(Errors.getResources(properties) - .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass())); + .getString(Errors.Keys.IllegalPropertyValueClass_2, key, value.getClass())); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -89,7 +89,7 @@ final class AuthorityFactories<T extends * Creates a new provider for factories of the given type. */ private AuthorityFactories(final Class<T> type) { - super(ServiceLoader.load(type)); + super(type); } /** Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1740152&r1=1740151&r2=1740152&view=diff ============================================================================== --- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original) +++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Wed Apr 20 14:53:31 2016 @@ -44,6 +44,8 @@ import org.opengis.metadata.extent.Exten import org.opengis.metadata.extent.GeographicBoundingBox; import org.opengis.referencing.operation.CoordinateOperation; import org.apache.sis.internal.metadata.AxisDirections; +import org.apache.sis.internal.referencing.PositionalAccuracyConstant; +import org.apache.sis.internal.referencing.CoordinateOperations; import org.apache.sis.internal.referencing.ReferencingUtilities; import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.referencing.cs.DefaultVerticalCS; @@ -51,6 +53,7 @@ import org.apache.sis.referencing.cs.Def import org.apache.sis.referencing.crs.DefaultGeographicCRS; import org.apache.sis.referencing.crs.DefaultVerticalCRS; import org.apache.sis.referencing.crs.DefaultCompoundCRS; +import org.apache.sis.referencing.operation.AbstractCoordinateOperation; import org.apache.sis.referencing.operation.CoordinateOperationContext; import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; import org.apache.sis.referencing.factory.UnavailableFactoryException; @@ -66,13 +69,34 @@ import static java.util.Collections.sing /** * Static methods working on {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}. - * The methods defined in this class can be grouped in two categories: + * The methods defined in this class can be grouped in three categories: * * <ul> * <li>Factory methods, the most notable one being {@link #forCode(String)}.</li> * <li>Methods providing information, like {@link #isHorizontalCRS(CoordinateReferenceSystem)}.</li> + * <li>Finding coordinate operations between a source and a target CRS.</li> * </ul> * + * <div class="section">Usage example</div> + * The most frequently used methods in this class are {@link #forCode forCode(…)}, {@link #fromWKT fromWKT(…)} + * and {@link #findOperation findOperation(…)}. An usage example is like below + * (see the <a href="http://sis.apache.org/book/tables/CoordinateReferenceSystems.html">Apache SIS™ Coordinate + * Reference System (CRS) codes</a> page for the complete list of EPSG codes): + * + * {@preformat java + * CoordinateReferenceSystem source = CRS.forCode("EPSG:4326"); // WGS 84 + * CoordinateReferenceSystem target = CRS.forCode("EPSG:3395"); // WGS 84 / World Mercator + * CoordinateOperation operation = CRS.findOperation(source, target, null); + * if (CRS.getLinearAccuracy(operation) > 100) { + * // If the accuracy is coarser than 100 metres (or any other threshold at application choice) + * // maybe the operation is not suitable. Decide here what to do (throw an exception, etc). + * } + * MathTransform mt = operation.getMathTransform(); + * DirectPosition position = new DirectPosition2D(20, 30); // 20°N 30°E (watch out axis order!) + * position = mt.transform(position, position); + * System.out.println(position); + * } + * * <div class="section">Note on kinds of CRS</div> * The {@link #getSingleComponents(CoordinateReferenceSystem)} method decomposes an arbitrary CRS into a flat * list of single components. In such flat list, vertical and temporal components can easily be identified by @@ -101,9 +125,10 @@ public final class CRS extends Static { /** * Returns the Coordinate Reference System for the given authority code. * The set of available codes depends on the {@link CRSAuthorityFactory} instances available on the classpath. - * There is many thousands of CRS defined by EPSG authority or by other authorities. + * There is many thousands of <a href="http://sis.apache.org/book/tables/CoordinateReferenceSystems.html">CRS + * defined by EPSG authority or by other authorities</a>. * The following table lists a very small subset of codes which are guaranteed to be available - * on any installation of Apache SIS version 0.4 or above: + * on any installation of Apache SIS: * * <blockquote><table class="sis"> * <caption>Minimal set of supported authority codes</caption> @@ -218,14 +243,141 @@ public final class CRS extends Static { } /** + * Creates a coordinate reference system object from a XML string. + * Note that the given argument is the XML document itself, <strong>not</strong> a URL to a XML document. + * For reading XML documents from readers or input streams, + * see static methods in the {@link org.apache.sis.xml.XML} class. + * + * @param xml Coordinate reference system encoded in XML format. + * @return The unmarshalled Coordinate Reference System. + * @throws FactoryException if the object creation failed. + * + * @see org.apache.sis.xml.XML#unmarshal(String) + * + * @since 0.7 + */ + public static CoordinateReferenceSystem fromXML(final String xml) throws FactoryException { + ArgumentChecks.ensureNonNull("text", xml); + return DefaultFactories.forBuildin(CRSFactory.class).createFromXML(xml); + } + + /** + * Finds a mathematical operation that transforms or converts coordinates from the given source to the + * given target coordinate reference system. If an estimation of the geographic area containing the points + * to transform is known, it can be specified for helping this method to find a better suited operation. + * + * <div class="note"><b>Note:</b> + * the area of interest is just one aspect that may affect the coordinate operation. + * Other aspects are the time of interest (because some coordinate operations take in account the + * plate tectonics movement) or the desired accuracy. For more control on the coordinate operation + * to create, see {@link CoordinateOperationContext}.</div> + * + * After the caller received a {@code CoordinateOperation} instance, the following methods can be invoked + * for checking if the operation suits the caller's needs: + * + * <ul> + * <li>{@link #getGeographicBoundingBox(CoordinateOperation)} + * for checking if the operation is valid in the caller's area of interest.</li> + * <li>{@link #getLinearAccuracy(CoordinateOperation)} + * for checking if the operation has sufficient accuracy for caller's purpose.</li> + * </ul> + * + * @param sourceCRS the CRS of source coordinates. + * @param targetCRS the CRS of target coordinates. + * @param areaOfInterest the area of interest, or {@code null} if none. + * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}. + * @throws FactoryException if the operation can not be created. + * + * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext) + * + * @since 0.7 + */ + public static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS, + final GeographicBoundingBox areaOfInterest) + throws FactoryException + { + ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS); + ArgumentChecks.ensureNonNull("targetCRS", targetCRS); + CoordinateOperationContext context = null; + if (areaOfInterest != null) { + if (areaOfInterest instanceof DefaultGeographicBoundingBox && ((DefaultGeographicBoundingBox) areaOfInterest).isEmpty()) { + throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "areaOfInterest")); + } + context = new CoordinateOperationContext(); + context.setAreaOfInterest(areaOfInterest); + } + return CoordinateOperations.factory().createOperation(sourceCRS, targetCRS, context); + } + + /** + * Returns a positional accuracy estimation in metres for the given operation, or {@code NaN} if unknown. + * This method applies the following heuristics: + * + * <ul> + * <li>If the given operation is an instance of {@link AbstractCoordinateOperation}, then delegate to the + * operation {@link AbstractCoordinateOperation#getLinearAccuracy() getLinearAccuracy()} method.</li> + * + * <li>Otherwise if at least one {@linkplain org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult + * quantitative result} is found with a linear unit, then return the largest value converted to metres.</li> + * + * <li>Otherwise if the operation is a {@linkplain org.apache.sis.referencing.operation.DefaultConversion + * conversion}, then returns 0 since a conversion is by definition accurate up to rounding errors.</li> + * + * <li>Otherwise if the operation is a {@linkplain org.apache.sis.referencing.operation.DefaultTransformation + * transformation}, then the returned value depends on whether the datum shift were applied with the help + * of Bursa-Wolf parameters of not.</li> + * </ul> + * + * See {@link AbstractCoordinateOperation#getLinearAccuracy()} for more details on the above heuristic rules. + * + * @param operation The coordinate operation for which to get the accuracy estimation, or {@code null}. + * @return The accuracy estimation (always in meters), or NaN if unknown. + * + * @see #findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox) + * + * @since 0.7 + */ + public static double getLinearAccuracy(final CoordinateOperation operation) { + if (operation == null) { + return Double.NaN; + } else if (operation instanceof AbstractCoordinateOperation) { + return ((AbstractCoordinateOperation) operation).getLinearAccuracy(); + } else { + return PositionalAccuracyConstant.getLinearAccuracy(operation); + } + } + + /** + * Returns the valid geographic area for the given coordinate operation, or {@code null} if unknown. + * This method explores the {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity} + * associated with the given operation. If more than one geographic bounding box is found, then they will be + * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) added} + * together. + * + * @param operation The coordinate operation for which to get the domain of validity, or {@code null}. + * @return The geographic area where the operation is valid, or {@code null} if unspecified. + * + * @see #findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox) + * @see Extents#getGeographicBoundingBox(Extent) + * + * @category information + * + * @since 0.7 + */ + public static GeographicBoundingBox getGeographicBoundingBox(final CoordinateOperation operation) { + return (operation != null) ? Extents.getGeographicBoundingBox(operation.getDomainOfValidity()) : null; + } + + /** * Returns the valid geographic area for the given coordinate reference system, or {@code null} if unknown. - * This method explores the {@linkplain CoordinateReferenceSystem#getDomainOfValidity() domain of validity} - * associated with the given CRS. If more than one geographic bounding box is found, then they will be - * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) - * added} together. + * This method explores the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getDomainOfValidity() domain of + * validity} associated with the given CRS. If more than one geographic bounding box is found, then they will be + * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) added} + * together. * - * @param crs The coordinate reference system, or {@code null}. - * @return The geographic area, or {@code null} if none. + * @param crs The coordinate reference system for which to get the domain of validity, or {@code null}. + * @return The geographic area where the coordinate reference system is valid, or {@code null} if unspecified. * * @see #getEnvelope(CoordinateReferenceSystem) * @see Extents#getGeographicBoundingBox(Extent) @@ -596,43 +748,4 @@ check: while (lower != 0 || upper != di } return AuthorityFactories.ALL.getAuthorityFactory(CRSAuthorityFactory.class, authority, null); } - - /** - * Finds a mathematical operation that transforms or converts coordinates from the given source to the - * given target coordinate reference system. If an estimation of the geographic area containing the points - * to transform is known, it can be specified for helping this method to find a better suited operation. - * - * <p>Note that the area of interest is just one aspect that may affect the coordinate operation. - * Other aspects are the time of interest (because some coordinate operations take in account the - * plate tectonics movement) or the desired accuracy. For more control on the coordinate operation - * to create, see {@link CoordinateOperationContext}.</p> - * - * @param sourceCRS the CRS of source coordinates. - * @param targetCRS the CRS of target coordinates. - * @param areaOfInterest the area of interest, or {@code null} if none. - * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}. - * @throws FactoryException if the operation can not be created. - * - * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext) - * - * @since 0.7 - */ - public static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS, - final CoordinateReferenceSystem targetCRS, - final GeographicBoundingBox areaOfInterest) - throws FactoryException - { - ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS); - ArgumentChecks.ensureNonNull("targetCRS", targetCRS); - CoordinateOperationContext context = null; - if (areaOfInterest != null) { - final DefaultGeographicBoundingBox bbox = DefaultGeographicBoundingBox.castOrCopy(areaOfInterest); - if (bbox.isEmpty()) { - throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "areaOfInterest")); - } - context = new CoordinateOperationContext(); - context.setGeographicBoundingBox(bbox); - } - return CoordinateOperations.factory.createOperation(sourceCRS, targetCRS, context); - } }
