sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1606678 - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/...
Date Mon, 30 Jun 2014 10:56:10 GMT
Author: desruisseaux
Date: Mon Jun 30 10:56:09 2014
New Revision: 1606678

URL: http://svn.apache.org/r1606678
Log:
Merge from the JDK7 branch.

Added:
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java
      - copied unchanged from r1606677, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineMatrix.java
      - copied unchanged from r1606677, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineMatrix.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java
      - copied unchanged from r1606677, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformTest.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/DefaultSource.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/DefaultScope.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LinearTransform1D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK8:r1606120-1606676
  Merged /sis/branches/JDK7:r1606123-1606677

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -137,21 +137,28 @@ public abstract class LegacyPropertyAdap
      * Returns the singleton value of the given collection, or {@code null} if the given collection is null or empty.
      * If the given collection contains more than one element, then a warning is emitted.
      *
+     * @param  <L>           The kind of legacy values to be returned.
      * @param  values        The collection from which to get the value.
      * @param  valueClass    The value class, used in case of warning only.
+     * @param  caller        Either {@code this} or {@code null}.
      * @param  callerClass   The caller class, used in case of warning only.
      * @param  callerMethod  The caller method, used in case of warning only.
      * @return The first value, or {@code null} if none.
      */
-    protected final L singleton(final Collection<? extends L> values, final Class<L> valueClass,
-            final Class<?> callerClass, final String callerMethod)
+    public static <L> L getSingleton(final Collection<? extends L> values, final Class<L> valueClass,
+            final LegacyPropertyAdapter<L,?> caller, final Class<?> callerClass, final String callerMethod)
     {
         if (values != null) {
             final Iterator<? extends L> it = values.iterator();
             if (it.hasNext()) {
                 final L value = it.next();
-                if (!warningOccurred && it.hasNext()) {
-                    warningOccurred = true;
+                if (it.hasNext()) {
+                    if (caller != null) {
+                        if (caller.warningOccurred) {
+                            return value; // Skip the warning.
+                        }
+                        caller.warningOccurred = true;
+                    }
                     MetadataUtilities.warning(callerClass, callerMethod,
                             Messages.Keys.IgnoredPropertiesAfterFirst_1, valueClass);
                 }

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -286,8 +286,8 @@ public class DefaultCoverageDescription 
 
             /** Extracts the legacy value from the new kind of value. */
             @Override protected RangeDimension unwrap(final AttributeGroup container) {
-                return singleton(container.getGroupAttributes(), RangeDimension.class,
-                        DefaultCoverageDescription.class, "getDimensions");
+                return getSingleton(container.getGroupAttributes(), RangeDimension.class,
+                        this, DefaultCoverageDescription.class, "getDimensions");
             }
 
             /** Updates the legacy value in an existing new kind of value. */

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/DefaultSource.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/DefaultSource.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/DefaultSource.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/lineage/DefaultSource.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -35,7 +35,6 @@ import org.opengis.referencing.Reference
 import org.apache.sis.metadata.iso.ISOMetadata;
 import org.apache.sis.metadata.iso.quality.DefaultScope;
 import org.apache.sis.metadata.iso.identification.DefaultResolution;
-import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.xml.Namespaces;
 
@@ -371,8 +370,12 @@ public class DefaultSource extends ISOMe
     @Deprecated
     @XmlElement(name = "sourceExtent")
     public final Collection<Extent> getSourceExtents() {
-        final Scope scope = getScope();
-        return LegacyPropertyAdapter.asCollection(scope != null ? scope.getExtent() : null);
+        Scope scope = getScope();
+        if (!(scope instanceof DefaultScope)) {
+            scope = new DefaultScope(scope);
+            setScope(scope);
+        }
+        return ((DefaultScope) scope).getExtents();
     }
 
     /**
@@ -385,15 +388,12 @@ public class DefaultSource extends ISOMe
      */
     @Deprecated
     public final void setSourceExtents(final Collection<? extends Extent> newValues) {
-        final Extent newValue = (newValues != null && !newValues.isEmpty()) ? newValues.iterator().next() : null;
-        final Scope scope = getScope();
-        if (scope instanceof DefaultScope) {
-            ((DefaultScope) scope).setExtent(newValue);
-        } else {
-            final DefaultScope s = new DefaultScope();
-            s.setExtent(newValue);
-            setScope(s);
+        Scope scope = getScope();
+        if (!(scope instanceof DefaultScope)) {
+            scope = new DefaultScope(scope);
+            setScope(scope);
         }
+        ((DefaultScope) scope).setExtents(newValues);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -371,8 +371,8 @@ public class DefaultMaintenanceInformati
 
             /** Extracts the legacy value from the new kind of value. */
             @Override protected ScopeDescription unwrap(final Scope container) {
-                return singleton(container.getLevelDescription(), ScopeDescription.class,
-                        DefaultMaintenanceInformation.class, "getUpdateScopeDescriptions");
+                return getSingleton(container.getLevelDescription(), ScopeDescription.class,
+                        this, DefaultMaintenanceInformation.class, "getUpdateScopeDescriptions");
             }
 
             /** Updates the legacy value in an existing new kind of value. */

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/DefaultScope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/DefaultScope.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/DefaultScope.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/DefaultScope.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -24,6 +24,7 @@ import org.opengis.metadata.extent.Exten
 import org.opengis.metadata.quality.Scope;
 import org.opengis.metadata.maintenance.ScopeCode;
 import org.opengis.metadata.maintenance.ScopeDescription;
+import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
 import org.apache.sis.metadata.iso.ISOMetadata;
 
 
@@ -33,7 +34,7 @@ import org.apache.sis.metadata.iso.ISOMe
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Touraïvane (IRD)
  * @since   0.3 (derived from geotk-2.1)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @XmlType(name = "DQ_Scope_Type", propOrder = {
@@ -46,7 +47,7 @@ public class DefaultScope extends ISOMet
     /**
      * Serial number for inter-operability with different versions.
      */
-    private static final long serialVersionUID = -1152756005841712646L;
+    private static final long serialVersionUID = 8357871602883209505L;
 
     /**
      * Hierarchical level of the data specified by the scope.
@@ -54,9 +55,9 @@ public class DefaultScope extends ISOMet
     private ScopeCode level;
 
     /**
-     * Information about the spatial, vertical and temporal extent of the data specified by the scope.
+     * Information about the spatial, vertical and temporal extent of the resource specified by the scope.
      */
-    private Extent extent;
+    private Collection<Extent> extents;
 
     /**
      * Detailed description about the level of the data specified by the scope.
@@ -91,7 +92,7 @@ public class DefaultScope extends ISOMet
         super(object);
         if (object != null) {
             level            = object.getLevel();
-            extent           = object.getExtent();
+            extents          = copyCollection(object.getExtents(), Extent.class);
             levelDescription = copyCollection(object.getLevelDescription(), ScopeDescription.class);
         }
     }
@@ -143,6 +144,29 @@ public class DefaultScope extends ISOMet
     }
 
     /**
+     * Returns information about the spatial, vertical and temporal extents of the resource specified by the scope.
+     *
+     * @return Information about the extent of the resource.
+     *
+     * @since 0.5
+     */
+    @Override
+    public Collection<Extent> getExtents() {
+        return extents = nonNullCollection(extents, Extent.class);
+    }
+
+    /**
+     * Sets information about the spatial, vertical and temporal extents of the resource specified by the scope.
+     *
+     * @param newValues New information about the extent of the resource.
+     *
+     * @since 0.5
+     */
+    public void setExtents(final Collection<? extends Extent> newValues) {
+        extents = writeCollection(newValues, extents, Extent.class);
+    }
+
+    /**
      * Returns detailed descriptions about the level of the data specified by the scope.
      *
      * @return Detailed description about the level of the data.
@@ -164,23 +188,29 @@ public class DefaultScope extends ISOMet
 
     /**
      * Information about the spatial, vertical and temporal extent of the data specified by the scope.
+     * This method fetches the value from the {@linkplain #getExtents() extents} collection.
      *
      * @return Information about the extent of the data, or {@code null}.
+     *
+     * @deprecated Replaced by {@link #getExtents()} as of ISO 19115:2014.
      */
     @Override
+    @Deprecated
     @XmlElement(name = "extent")
-    public Extent getExtent() {
-        return extent;
+    public final Extent getExtent() {
+        return LegacyPropertyAdapter.getSingleton(extents, Extent.class, null, DefaultScope.class, "getExtent");
     }
 
     /**
-     * Sets information about the spatial, vertical and temporal extent of the data specified
-     * by the scope.
+     * Sets information about the spatial, vertical and temporal extent of the data specified by the scope.
+     * This method stores the value in the {@linkplain #setExtents(Collection) extents} collection.
      *
      * @param newValue The new extent.
+     *
+     * @deprecated Replaced by {@link #setExtents(Collection)} as of ISO 19115:2014.
      */
-    public void setExtent(final Extent newValue) {
-        checkWritePermission();
-        extent = newValue;
+    @Deprecated
+    public final void setExtent(final Extent newValue) {
+        setExtents(LegacyPropertyAdapter.asCollection(newValue));
     }
 }

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -153,7 +153,7 @@ public final strictfp class AllMetadataT
             org.opengis.metadata.lineage.Processing.class,
             org.opengis.metadata.lineage.ProcessStep.class,
             org.opengis.metadata.lineage.ProcessStepReport.class,
-// TODO     org.opengis.metadata.lineage.Source.class,
+            org.opengis.metadata.lineage.Source.class,
             org.opengis.metadata.maintenance.MaintenanceFrequency.class,
             org.opengis.metadata.maintenance.MaintenanceInformation.class,
             org.opengis.metadata.maintenance.MetadataScope.class,

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -62,18 +62,22 @@ public class AffineTransform2D extends I
     private static final long serialVersionUID = -5299837898367149069L;
 
     /**
-     * The inverse transform. This field will be computed only when needed.
+     * The matrix, or {@code null} if not yet computed.
+     *
+     * <p>This field is also used for determining if the affine transform is mutable.
+     * If this field is {@code null} (which should be a temporary state), then this means that
+     * this affine transform is still under construction. This field <strong>must</strong> be
+     * set to a non-null value before an {@link AffineTransform2D} instance is published.</p>
+     *
+     * @see #getMatrix()
+     * @see #freeze()
      */
-    private transient volatile AffineTransform2D inverse;
+    private AffineMatrix matrix;
 
     /**
-     * {@code true} if this transform is mutable. This field may be temporarily set
-     * to {@code true} during construction, but <strong>must</strong> be reset to
-     * {@code false} before an {@link AffineTransform2D} instance is published.
-     *
-     * @see #freeze()
+     * The inverse transform. This field will be computed only when needed.
      */
-    private transient boolean mutable;
+    private transient volatile AffineTransform2D inverse;
 
     /**
      * Constructs a <strong>temporarily mutable</strong> identity affine transform.
@@ -82,7 +86,6 @@ public class AffineTransform2D extends I
      */
     public AffineTransform2D() {
         super();
-        mutable = true;
     }
 
     /**
@@ -94,7 +97,9 @@ public class AffineTransform2D extends I
      */
     public AffineTransform2D(final AffineTransform transform, final boolean mutable) {
         super(transform);
-        this.mutable = mutable;
+        if (!mutable) {
+            freeze();
+        }
     }
 
     /**
@@ -104,9 +109,20 @@ public class AffineTransform2D extends I
      */
     public AffineTransform2D(final AffineTransform transform) {
         super(transform);
-        mutable = true;
         forcePositiveZeros();
-        mutable = false;
+        freeze();
+    }
+
+    /**
+     * Constructs a new {@code AffineTransform2D} from the given 9 or 18 values.
+     *
+     * @param elements The matrix elements, optionally with error terms.
+     */
+    public AffineTransform2D(final double[] elements) {
+        super(pz(elements[0]), pz(elements[3]),
+              pz(elements[1]), pz(elements[4]),
+              pz(elements[2]), pz(elements[5]));
+        matrix = new AffineMatrix(this, elements);
     }
 
     /**
@@ -124,6 +140,7 @@ public class AffineTransform2D extends I
      */
     public AffineTransform2D(double m00, double m10, double m01, double m11, double m02, double m12) {
         super(pz(m00), pz(m10), pz(m01), pz(m11), pz(m02), pz(m12));
+        freeze();
     }
 
     /**
@@ -150,9 +167,11 @@ public class AffineTransform2D extends I
 
     /**
      * Makes this {@code AffineTransform2D} immutable.
+     * This method shall be invoked exactly once.
      */
     public final void freeze() {
-        mutable = false;
+        assert matrix == null;
+        matrix = new AffineMatrix(this, null);
     }
 
     /**
@@ -163,7 +182,7 @@ public class AffineTransform2D extends I
      */
     @Override
     protected final void checkPermission() throws UnsupportedOperationException {
-        if (!mutable) {
+        if (matrix != null) {
             super.checkPermission();
         }
     }
@@ -261,7 +280,7 @@ public class AffineTransform2D extends I
      */
     @Override
     public final Matrix getMatrix() {
-        return AffineTransforms2D.toMatrix(this);
+        return matrix;
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -22,6 +22,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.DoubleDouble;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
 
 
 /**
@@ -35,12 +36,12 @@ import org.apache.sis.internal.util.Doub
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-2.2)
- * @version 0.4
+ * @version 0.5
  * @module
  *
  * @see Matrices#createDiagonal(int, int)
  */
-class GeneralMatrix extends MatrixSIS {
+class GeneralMatrix extends MatrixSIS implements ExtendedPrecisionMatrix {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -132,8 +133,13 @@ class GeneralMatrix extends MatrixSIS {
         ensureValidSize(numRow, numCol);
         this.numRow = (short) numRow;
         this.numCol = (short) numCol;
-        elements = new double[numRow * numCol];
-        getElements(matrix, numRow, numCol, elements);
+        if (matrix instanceof ExtendedPrecisionMatrix) {
+            elements = ((ExtendedPrecisionMatrix) matrix).getExtendedElements();
+            assert (elements.length % (numRow * numCol)) == 0;
+        } else {
+            elements = new double[numRow * numCol];
+            getElements(matrix, numRow, numCol, elements);
+        }
     }
 
     /**
@@ -320,6 +326,15 @@ class GeneralMatrix extends MatrixSIS {
     }
 
     /**
+     * Returns a copy of all matrix elements, potentially followed by the error terms for extended-precision arithmetic.
+     * Matrix elements are returned in a flat, row-major (column indices vary fastest) array.
+     */
+    @Override
+    public final double[] getExtendedElements() {
+        return elements.clone();
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -30,6 +30,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.referencing.AxisDirections;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk7.JDK7;
@@ -64,7 +65,7 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-2.2)
- * @version 0.4
+ * @version 0.5
  * @module
  */
 public final class Matrices extends Static {
@@ -678,11 +679,13 @@ public final class Matrices extends Stat
         if (size != matrix.getNumCol()) {
             return new NonSquareMatrix(matrix);
         }
-        switch (size) {
-            case 1: return new Matrix1(matrix);
-            case 2: return new Matrix2(matrix);
-            case 3: return new Matrix3(matrix);
-            case 4: return new Matrix4(matrix);
+        if (!(matrix instanceof ExtendedPrecisionMatrix)) {
+            switch (size) {
+                case 1: return new Matrix1(matrix);
+                case 2: return new Matrix2(matrix);
+                case 3: return new Matrix3(matrix);
+                case 4: return new Matrix4(matrix);
+            }
         }
         return new GeneralMatrix(matrix);
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -33,7 +33,6 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.SingleOperation;
 import org.apache.sis.geometry.GeneralDirectPosition;
 import org.apache.sis.parameter.Parameterized;
-import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.FormattableObject;
@@ -867,51 +866,6 @@ public abstract class AbstractMathTransf
     }
 
     /**
-     * Helper method for implementation of {@link #equals(Object, ComparisonMode)} methods in
-     * {@link LinearTransform} implementations. Those implementations shall replace completely the
-     * {@link #equals(Object, ComparisonMode)} default implementation, <strong>except</strong> for
-     * {@link ComparisonMode#STRICT} which should continue to rely on the default implementation.
-     * The pattern is:
-     *
-     * {@preformat java
-     *     public boolean equals(Object object, ComparisonMode mode) {
-     *         if (object == this) { // Slight optimization
-     *             return true;
-     *         }
-     *         if (mode != ComparisonMode.STRICT) {
-     *             return equals(this, object, mode);
-     *         }
-     *         if (super.equals(object, mode)) {
-     *             // Compare the internal fields here.
-     *         }
-     *         return false;
-     *     }
-     * }
-     *
-     * Note that this pattern considers {@link ComparisonMode#BY_CONTRACT} as synonymous to
-     * {@code IGNORE_METADATA} rather than {@code STRICT}. This is valid if we consider that
-     * the behavior of the math transform is completely specified by its matrix.
-     *
-     * @param  t1  The first transform to compare.
-     * @param  t2  The second transform to compare, or {@code null} if none.
-     * @param  mode The strictness level of the comparison.
-     * @return {@code true} if both transforms are equal.
-     */
-    static boolean equals(final LinearTransform t1, final Object t2, final ComparisonMode mode) {
-        if (t2 instanceof LinearTransform) {
-            final Matrix m1 = t1.getMatrix();
-            if (m1 != null) {
-                final Matrix m2 = ((LinearTransform) t2).getMatrix();
-                if (m1 instanceof LenientComparable) {
-                    return ((LenientComparable) m1).equals(m2, mode);
-                }
-                return Matrices.equals(m1, m2, mode);
-            }
-        }
-        return false;
-    }
-
-    /**
      * Formats the inner part of a <cite>Well Known Text</cite> version 1 (WKT 1) element.
      * The default implementation formats all parameter values returned by {@link #getParameterValues()}.
      * The parameter group name is used as the math transform name.
@@ -944,7 +898,7 @@ public abstract class AbstractMathTransf
      * @see AbstractMathTransform2D#beforeFormat(List, int, boolean)
      * @see ConcatenatedTransform#getPseudoSteps()
      */
-    int beforeFormat(List<MathTransform> transforms, int index, boolean inverse) {
+    int beforeFormat(List<Object> transforms, int index, boolean inverse) {
         return index;
     }
 

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -26,7 +26,6 @@ import java.awt.geom.PathIterator;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.IllegalPathStateException;
 import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform2D;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
@@ -103,8 +102,15 @@ public abstract class AbstractMathTransf
      */
     @Override
     public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException {
+        return transform(this, ptSrc, ptDst);
+    }
+
+    /**
+     * Implementation of {@link #transform(DirectPosition, DirectPosition)} shared by the inverse transform.
+     */
+    static Point2D transform(final AbstractMathTransform tr, final Point2D ptSrc, final Point2D ptDst) throws TransformException {
         final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};
-        transform(ord, 0, ord, 0, false);
+        tr.transform(ord, 0, ord, 0, false);
         if (ptDst != null) {
             ptDst.setLocation(ord[0], ord[1]);
             return ptDst;
@@ -285,8 +291,15 @@ public abstract class AbstractMathTransf
      */
     @Override
     public Matrix derivative(final Point2D point) throws TransformException {
+        return derivative(this, point);
+    }
+
+    /**
+     * Implementation of {@link #derivative(DirectPosition)} shared by the inverse transform.
+     */
+    static Matrix derivative(final AbstractMathTransform tr, final Point2D point) throws TransformException {
         final double[] coordinate = new double[] {point.getX(), point.getY()};
-        final Matrix derivative = transform(coordinate, 0, null, 0, true);
+        final Matrix derivative = tr.transform(coordinate, 0, null, 0, true);
         if (derivative == null) {
             throw new TransformException(Errors.format(Errors.Keys.CanNotComputeDerivative));
         }
@@ -340,11 +353,66 @@ public abstract class AbstractMathTransf
         }
 
         /**
+         * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+         * The default implementation invokes {@link #transform(double[], int, double[], int, boolean)}
+         * using a temporary array of doubles.
+         *
+         * @param  ptSrc The coordinate point to be transformed.
+         * @param  ptDst The coordinate point that stores the result of transforming {@code ptSrc},
+         *               or {@code null} if a new point shall be created.
+         * @return The coordinate point after transforming {@code ptSrc} and storing the result in {@code ptDst},
+         *         or in a new point if {@code ptDst} was null.
+         * @throws TransformException If the point can not be transformed.
+         *
+         * @see MathTransform2D#transform(Point2D, Point2D)
+         */
+        @Override
+        public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException {
+            return AbstractMathTransform2D.transform(this, ptSrc, ptDst);
+        }
+
+        /**
+         * Transforms the specified shape. The default implementation computes quadratic curves
+         * using three points for each line segment in the shape. The returned object is often
+         * a {@link Path2D}, but may also be a {@link Line2D} or a {@link QuadCurve2D} if such
+         * simplification is possible.
+         *
+         * @param  shape Shape to transform.
+         * @return Transformed shape, or {@code shape} if this transform is the identity transform.
+         * @throws TransformException if a transform failed.
+         */
+        @Override
+        public Shape createTransformedShape(final Shape shape) throws TransformException {
+            return isIdentity() ? shape : AbstractMathTransform2D.createTransformedShape(this, shape, null, null, false);
+        }
+
+        /**
+         * Gets the derivative of this transform at a point.
+         * The default implementation performs the following steps:
+         *
+         * <ul>
+         *   <li>Copy the coordinate in a temporary array and pass that array to the
+         *       {@link #transform(double[], int, double[], int, boolean)} method,
+         *       with the {@code derivate} boolean argument set to {@code true}.</li>
+         *   <li>If the later method returned a non-null matrix, returns that matrix.
+         *       Otherwise throws {@link TransformException}.</li>
+         * </ul>
+         *
+         * @param  point The coordinate point where to evaluate the derivative.
+         * @return The derivative at the specified point as a 2×2 matrix.
+         * @throws TransformException if the derivative can not be evaluated at the specified point.
+         */
+        @Override
+        public Matrix derivative(final Point2D point) throws TransformException {
+            return AbstractMathTransform2D.derivative(this, point);
+        }
+
+        /**
          * Same work than {@link AbstractMathTransform2D#beforeFormat(List, int, boolean)}
          * but with the knowledge that this transform is an inverse transform.
          */
         @Override
-        final int beforeFormat(final List<MathTransform> transforms, final int index, final boolean inverse) {
+        final int beforeFormat(final List<Object> transforms, final int index, final boolean inverse) {
             return AbstractMathTransform2D.this.beforeFormat(transforms, index, !inverse);
         }
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -30,6 +30,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.parameter.Parameterized;
+import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.internal.referencing.Semaphores;
 import org.apache.sis.util.Classes;
@@ -38,6 +39,7 @@ import org.apache.sis.util.ComparisonMod
 import org.apache.sis.util.Utilities;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.util.resources.Errors;
 
 
@@ -63,6 +65,16 @@ class ConcatenatedTransform extends Abst
     private static final long serialVersionUID = 5772066656987558634L;
 
     /**
+     * Tolerance threshold for considering a matrix as identity. Since the value used here is smaller
+     * than 1 ULP (about 2.22E-16), it applies only the the zero terms in the matrix. The terms on the
+     * diagonal are still expected to be exactly 1.
+     *
+     * @todo Try to remove completely this tolerance threshold after we applied double-double arithmetic
+     *       to all matrices.
+     */
+    private static final double IDENTITY_TOLERANCE = 1E-16;
+
+    /**
      * The first math transform.
      */
     protected final MathTransform transform1;
@@ -229,6 +241,9 @@ class ConcatenatedTransform extends Abst
             final Matrix matrix2 = MathTransforms.getMatrix(tr2);
             if (matrix2 != null) {
                 final Matrix matrix = MatrixSIS.castOrCopy(matrix2).multiply(matrix1);
+                if (Matrices.isIdentity(matrix, IDENTITY_TOLERANCE)) {
+                    return MathTransforms.identity(matrix.getNumRow() - 1);
+                }
                 /*
                  * NOTE: It is quite tempting to "fix rounding errors" in the matrix before to create the transform.
                  * But this is often wrong for datum shift transformations (Molodensky and the like) since the datum
@@ -409,11 +424,11 @@ class ConcatenatedTransform extends Abst
      * (<var>normalize</var>, <var>unitary projection</var>, <var>denormalize</var>) tuples are replaced by single
      * (<var>projection</var>) elements, which does not need to be instances of {@link MathTransform}.
      */
-    private List<MathTransform> getPseudoSteps() {
-        final List<MathTransform> transforms = new ArrayList<MathTransform>();
+    private List<Object> getPseudoSteps() {
+        final List<Object> transforms = new ArrayList<Object>();
         getSteps(transforms);
         /*
-         * Pre-process the transforms before to format. Some steps may be* merged, or new
+         * Pre-process the transforms before to format. Some steps may be merged, or new
          * steps may be created. Do not move size() out of the loop, because it may change.
          */
         for (int i=0; i<transforms.size(); i++) {
@@ -430,7 +445,7 @@ class ConcatenatedTransform extends Abst
      *
      * @param transforms The list where to add concatenated transforms.
      */
-    private void getSteps(final List<MathTransform> transforms) {
+    private void getSteps(final List<? super MathTransform> transforms) {
         if (transform1 instanceof ConcatenatedTransform) {
             ((ConcatenatedTransform) transform1).getSteps(transforms);
         } else {
@@ -468,7 +483,7 @@ class ConcatenatedTransform extends Abst
      */
     private Parameterized getParameterised() {
         Parameterized param = null;
-        final List<MathTransform> transforms = getPseudoSteps();
+        final List<Object> transforms = getPseudoSteps();
         if (transforms.size() == 1 || Semaphores.query(Semaphores.PROJCS)) {
             for (final Object candidate : transforms) {
                 if (!(candidate instanceof Parameterized)) {
@@ -888,7 +903,7 @@ class ConcatenatedTransform extends Abst
      */
     @Override
     public String formatTo(final Formatter formatter) {
-        final List<MathTransform> transforms;
+        final List<? super MathTransform> transforms;
         if (formatter.getConvention() == Convention.INTERNAL) {
             transforms = getSteps();
         } else {
@@ -902,9 +917,13 @@ class ConcatenatedTransform extends Abst
         if (transforms.size() == 1) {
             return formatter.delegateTo(transforms.get(0));
         }
-        for (final MathTransform step : transforms) {
+        for (final Object step : transforms) {
             formatter.newLine();
-            formatter.append(step);
+            if (step instanceof FormattableObject) {
+                formatter.append((FormattableObject) step); // May not implement MathTransform.
+            } else {
+                formatter.append((MathTransform) step);
+            }
         }
         return "Concat_MT";
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -426,9 +426,10 @@ final class CopyTransform extends Abstra
             return true;
         }
         if (mode != ComparisonMode.STRICT) {
-            return equals(this, object, mode);
-        }
-        if (super.equals(object, mode)) {
+            if (object instanceof LinearTransform) {
+                return Matrices.equals(getMatrix(), ((LinearTransform) object).getMatrix(), mode);
+            }
+        } else if (super.equals(object, mode)) {
             final CopyTransform that = (CopyTransform) object;
             return srcDim == that.srcDim && Arrays.equals(indices, that.indices);
         }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -259,11 +259,11 @@ final class IdentityTransform extends Ab
             return true;
         }
         if (mode != ComparisonMode.STRICT) {
-            return equals(this, object, mode);
-        }
-        if (super.equals(object, mode)) {
-            final IdentityTransform that = (IdentityTransform) object;
-            return this.dimension == that.dimension;
+            if (object instanceof LinearTransform) {
+                return Matrices.equals(getMatrix(), ((LinearTransform) object).getMatrix(), mode);
+            }
+        } else if (super.equals(object, mode)) {
+            return ((IdentityTransform) object).dimension == dimension;
         }
         return false;
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LinearTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LinearTransform1D.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LinearTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LinearTransform1D.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -24,6 +24,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.Matrix1;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.provider.Affine;
@@ -310,9 +311,10 @@ class LinearTransform1D extends Abstract
             return true;
         }
         if (mode != ComparisonMode.STRICT) {
-            return equals(this, object, mode);
-        }
-        if (super.equals(object, mode)) {
+            if (object instanceof LinearTransform) {
+                return Matrices.equals(getMatrix(), ((LinearTransform) object).getMatrix(), mode);
+            }
+        } else if (super.equals(object, mode)) {
             final LinearTransform1D that = (LinearTransform1D) object;
             return doubleToRawLongBits(this.scale)  == doubleToRawLongBits(that.scale) &&
                    doubleToRawLongBits(this.offset) == doubleToRawLongBits(that.offset);

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -27,6 +27,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.apache.sis.internal.referencing.DirectPositionView;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
 import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
 import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
 import org.apache.sis.referencing.operation.matrix.Matrices;
@@ -119,11 +120,19 @@ public final class MathTransforms extend
             }
             if (Matrices.isAffine(matrix)) {
                 switch (sourceDimension) {
-                    case 1: return linear(matrix.getElement(0,0), matrix.getElement(0,1));
-                    case 2: return new AffineTransform2D(
-                            matrix.getElement(0,0), matrix.getElement(1,0),
-                            matrix.getElement(0,1), matrix.getElement(1,1),
-                            matrix.getElement(0,2), matrix.getElement(1,2));
+                    case 1: {
+                        return linear(matrix.getElement(0,0), matrix.getElement(0,1));
+                    }
+                    case 2: {
+                        if (matrix instanceof ExtendedPrecisionMatrix) {
+                            return new AffineTransform2D(((ExtendedPrecisionMatrix) matrix).getExtendedElements());
+                        } else {
+                            return new AffineTransform2D(
+                                    matrix.getElement(0,0), matrix.getElement(1,0),
+                                    matrix.getElement(0,1), matrix.getElement(1,1),
+                                    matrix.getElement(0,2), matrix.getElement(1,2));
+                        }
+                    }
                 }
             } else if (sourceDimension == 2) {
                 return new ProjectiveTransform2D(matrix);

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -85,7 +85,7 @@ public class PassThroughTransform extend
      * The sub-transform to apply on the {@linkplain #getModifiedCoordinates() modified coordinates}.
      * This is often the sub-transform specified at construction time, but not necessarily.
      */
-    protected final MathTransform subTransform;
+    final MathTransform subTransform;
 
     /**
      * The inverse transform. This field will be computed only when needed,
@@ -275,6 +275,16 @@ public class PassThroughTransform extend
     }
 
     /**
+     * Returns the sub-transform to apply on the {@linkplain #getModifiedCoordinates() modified coordinates}.
+     * This is often the sub-transform specified at construction time, but not necessarily.
+     *
+     * @return The sub-transform.
+     */
+    public final MathTransform getSubTransform() {
+        return subTransform;
+    }
+
+    /**
      * Tests whether this transform does not move any points. A {@code PassThroughTransform}
      * is identity if the {@linkplain #subTransform sub-transform} is also identity.
      *

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -29,6 +29,9 @@ import org.apache.sis.parameter.TensorPa
 import org.apache.sis.referencing.operation.provider.Affine;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -46,7 +49,9 @@ import org.apache.sis.referencing.operat
  *
  * @see java.awt.geom.AffineTransform
  */
-class ProjectiveTransform extends AbstractMathTransform implements LinearTransform, Serializable {
+class ProjectiveTransform extends AbstractMathTransform implements LinearTransform, ExtendedPrecisionMatrix,
+        Serializable // Not Cloneable, despite the clone() method.
+{
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -64,6 +69,9 @@ class ProjectiveTransform extends Abstra
 
     /**
      * Elements of the matrix. Column indices vary fastest.
+     *
+     * <p>This array may have twice the normal length ({@link #numRow} × {@link #numCol}),
+     * in which case the second half contains the error terms in double-double arithmetic.</p>
      */
     private final double[] elt;
 
@@ -83,11 +91,16 @@ class ProjectiveTransform extends Abstra
     protected ProjectiveTransform(final Matrix matrix) {
         numRow = matrix.getNumRow();
         numCol = matrix.getNumCol();
-        elt = new double[numRow * numCol];
-        int mix = 0;
-        for (int j=0; j<numRow; j++) {
-            for (int i=0; i<numCol; i++) {
-                elt[mix++] = matrix.getElement(j,i);
+        if (matrix instanceof ExtendedPrecisionMatrix) {
+            elt = ((ExtendedPrecisionMatrix) matrix).getExtendedElements();
+            assert (elt.length % (numRow * numCol)) == 0;
+        } else {
+            elt = new double[numRow * numCol];
+            int mix = 0;
+            for (int j=0; j<numRow; j++) {
+                for (int i=0; i<numCol; i++) {
+                    elt[mix++] = matrix.getElement(j,i);
+                }
             }
         }
     }
@@ -109,27 +122,19 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Tests whether this transform does not move any points.
-     *
-     * <span class="note"><b>Note:</b> this method should always returns {@code false}, since
-     * {@code MathTransforms.linear(…)} should have created specialized implementations for identity cases.
-     * Nevertheless we perform the full check as a safety, in case someone instantiated this class directly
-     * instead than using a factory method.</span>
+     * Gets the number of rows in the matrix.
      */
     @Override
-    public boolean isIdentity() {
-        if (numRow != numCol) {
-            return false;
-        }
-        int mix = 0;
-        for (int j=0; j<numRow; j++) {
-            for (int i=0; i<numCol; i++) {
-                if (elt[mix++] != (i == j ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-        return true;
+    public final int getNumRow() {
+        return numRow;
+    }
+
+    /**
+     * Gets the number of columns in the matrix.
+     */
+    @Override
+    public final int getNumCol() {
+        return numCol;
     }
 
     /**
@@ -137,7 +142,7 @@ class ProjectiveTransform extends Abstra
      */
     @Override
     public final Matrix getMatrix() {
-        return Matrices.create(numRow, numCol, elt);
+        return this;
     }
 
     /**
@@ -162,6 +167,66 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
+     * Returns a copy of matrix elements, including error terms if any.
+     */
+    @Override
+    public final double[] getExtendedElements() {
+        return elt.clone();
+    }
+
+    /**
+     * Returns the matrix element at the given index.
+     */
+    @Override
+    public final double getElement(final int row, final int column) {
+        ArgumentChecks.ensureBetween("row",    0, numRow - 1, row);
+        ArgumentChecks.ensureBetween("column", 0, numCol - 1, column);
+        return elt[row * numCol + column];
+    }
+
+    /**
+     * Unsupported operation, since this matrix is unmodifiable.
+     */
+    @Override
+    public final void setElement(final int row, final int column, final double value) {
+        throw new UnsupportedOperationException(Matrices.isAffine(this)
+                ? Errors.format(Errors.Keys.UnmodifiableAffineTransform)
+                : Errors.format(Errors.Keys.UnmodifiableObject_1, ProjectiveTransform.class));
+    }
+
+    /**
+     * Returns a copy of the matrix that user can modify.
+     */
+    @Override
+    public final Matrix clone() {
+        return Matrices.copy(this);
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     *
+     * <span class="note"><b>Note:</b> this method should always returns {@code false}, since
+     * {@code MathTransforms.linear(…)} should have created specialized implementations for identity cases.
+     * Nevertheless we perform the full check as a safety, in case someone instantiated this class directly
+     * instead than using a factory method.</span>
+     */
+    @Override
+    public boolean isIdentity() {
+        if (numRow != numCol) {
+            return false;
+        }
+        int mix = 0;
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                if (elt[mix++] != (i == j ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
      * Converts a single coordinate point in a list of ordinal values,
      * and optionally computes the derivative at that location.
      *
@@ -415,7 +480,7 @@ class ProjectiveTransform extends Abstra
              *           inverse = this;
              *       } else { ... }
              */
-            MatrixSIS matrix = Matrices.create(numRow, numCol, elt);
+            MatrixSIS matrix = Matrices.copy(this);
             matrix = matrix.inverse();
             ProjectiveTransform inv = createInverse(matrix);
             inv.inverse = this;
@@ -453,9 +518,10 @@ class ProjectiveTransform extends Abstra
             return true;
         }
         if (mode != ComparisonMode.STRICT) {
-            return equals(this, object, mode);
-        }
-        if (super.equals(object, mode)) {
+            if (object instanceof LinearTransform) {
+                return Matrices.equals(this, ((LinearTransform) object).getMatrix(), mode);
+            }
+        } else if (super.equals(object, mode)) {
             final ProjectiveTransform that = (ProjectiveTransform) object;
             return this.numRow == that.numRow &&
                    this.numCol == that.numCol &&

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1606678&r1=1606677&r2=1606678&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Mon Jun 30 10:56:09 2014
@@ -48,6 +48,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.transform.ExponentialTransform1DTest.class,
     org.apache.sis.referencing.operation.transform.CopyTransformTest.class,
     org.apache.sis.referencing.operation.transform.PassThroughTransformTest.class,
+    org.apache.sis.referencing.operation.transform.ConcatenatedTransformTest.class,
     org.apache.sis.referencing.operation.transform.TransferFunctionTest.class,
 
     org.apache.sis.internal.referencing.FormulasTest.class,



Mime
View raw message