sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1813520 [2/3] - in /sis/branches/JDK7: ./ core/sis-feature/src/main/java/org/apache/sis/feature/builder/ core/sis-feature/src/main/java/org/apache/sis/internal/feature/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/ co...
Date Fri, 27 Oct 2017 12:31:46 GMT
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -33,7 +33,10 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.internal.metadata.AxisDirections;
+import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.referencing.provider.Affine;
+import org.apache.sis.internal.referencing.provider.DatumShiftMethod;
 import org.apache.sis.internal.referencing.provider.Geographic2Dto3D;
 import org.apache.sis.internal.referencing.provider.Geographic3Dto2D;
 import org.apache.sis.internal.referencing.provider.GeographicToGeocentric;
@@ -114,17 +117,6 @@ import static org.apache.sis.util.Utilit
  */
 public class CoordinateOperationFinder extends CoordinateOperationRegistry {
     /**
-     * The accuracy threshold (in metres) for allowing the use of Molodensky approximation instead than the
-     * Geocentric Translation method. The accuracy of datum shifts with Molodensky approximation is about 5
-     * or 10 metres. However for this constant, we are not interested in absolute accuracy but rather in the
-     * difference between Molodensky and Geocentric Translation methods, which is much lower (less than 1 m).
-     * We nevertheless use a relatively high threshold as a conservative approach.
-     *
-     * @see #desiredAccuracy
-     */
-    private static final double MOLODENSKY_ACCURACY = 5;
-
-    /**
      * Identifiers used as the basis for identifier of CRS used as an intermediate step.
      * The values can be of two kinds:
      *
@@ -440,7 +432,7 @@ public class CoordinateOperationFinder e
          * Actually we do not know if the longitude rotation should be before or after datum shift. But this ambiguity
          * can usually be ignored because Bursa-Wolf parameters are always used with source and target prime meridians
          * set to Greenwich in EPSG dataset 8.9.  For safety, the SIS's DefaultGeodeticDatum class ensures that if the
-         * prime meridian are not the same, then the target meridian must be Greenwich.
+         * prime meridians are not the same, then the target meridian must be Greenwich.
          */
         final DefaultMathTransformFactory.Context context = ReferencingUtilities.createTransformContext(
                 sourceCRS, targetCRS, new MathTransformContext(sourceDatum, targetDatum));
@@ -496,20 +488,34 @@ public class CoordinateOperationFinder e
         final DefaultMathTransformFactory mtFactory = factorySIS.getDefaultMathTransformFactory();
         MathTransform before = null, after = null;
         ParameterValueGroup parameters;
-        if (datumShift != null) {
+        if (identifier == DATUM_SHIFT || identifier == ELLIPSOID_CHANGE) {
             /*
              * If the transform can be represented by a single coordinate operation, returns that operation.
              * Possible operations are:
              *
-             *    - Geocentric translation         (in geocentric, geographic-2D or geographic-3D domains)
              *    - Position Vector transformation (in geocentric, geographic-2D or geographic-3D domains)
+             *    - Geocentric translation         (in geocentric, geographic-2D or geographic-3D domains)
+             *    - [Abridged] Molodensky          (as an approximation of geocentric translation)
+             *    - Identity                       (if the desired accuracy is so large than we can skip datum shift)
              *
-             * Otherwise, maybe we failed to create the operation because the coordinate system type were not the same.
-             * Convert unconditionally to XYZ geocentric coordinates and apply the datum shift in that coordinate space.
+             * TODO: if both CS are ellipsoidal but with different number of dimensions, then we should use
+             * an intermediate 3D geographic CRS in order to enable the use of Molodensky method if desired.
              */
-            parameters = GeocentricAffine.createParameters(sourceCS, targetCS, datumShift, desiredAccuracy >= MOLODENSKY_ACCURACY);
+            final DatumShiftMethod preferredMethod = DatumShiftMethod.forAccuracy(desiredAccuracy);
+            parameters = GeocentricAffine.createParameters(sourceCS, targetCS, datumShift, preferredMethod);
             if (parameters == null) {
-                parameters = TensorParameters.WKT1.createValueGroup(properties(Constants.AFFINE), datumShift);
+                /*
+                 * Failed to select a coordinate operation. Maybe because the coordinate system types are not the same.
+                 * Convert unconditionally to XYZ geocentric coordinates and apply the datum shift in that CS space.
+                 *
+                 * TODO: operation name should not be "Affine" if 'before' or 'after' transforms are not identity.
+                 *       Reminder: the parameter group name here determines the OperationMethod later in this method.
+                 */
+                if (datumShift != null) {
+                    parameters = TensorParameters.WKT1.createValueGroup(properties(Constants.AFFINE), datumShift);
+                } else {
+                    parameters = Affine.identity(3);                        // Dimension of geocentric CRS.
+                }
                 final CoordinateSystem normalized = CommonCRS.WGS84.geocentric().getCoordinateSystem();
                 before = mtFactory.createCoordinateSystemChange(sourceCS, normalized, sourceDatum.getEllipsoid());
                 after  = mtFactory.createCoordinateSystemChange(normalized, targetCS, targetDatum.getEllipsoid());
@@ -520,18 +526,26 @@ public class CoordinateOperationFinder e
             parameters = (isGeographicToGeocentric ? GeographicToGeocentric.PARAMETERS
                                                    : GeocentricToGeographic.PARAMETERS).createValue();
         } else {
+            /*
+             * Coordinate system change (including change in the number of dimensions) without datum shift.
+             */
             final int sourceDim = sourceCS.getDimension();
             final int targetDim = targetCS.getDimension();
-            if ((sourceDim & ~1) == 2 && (sourceDim ^ targetDim) == 1    // sourceDim == 2 or 3 and difference with targetDim is 1.
+            if ((sourceDim & ~1) == 2                           // sourceDim == 2 or 3.
+                    && (sourceDim ^ targetDim) == 1             // abs(sourceDim - targetDim) == 1.
                     && (sourceCS instanceof EllipsoidalCS)
                     && (targetCS instanceof EllipsoidalCS))
             {
                 parameters = (sourceDim == 2 ? Geographic2Dto3D.PARAMETERS
                                              : Geographic3Dto2D.PARAMETERS).createValue();
             } else {
-                parameters = TensorParameters.WKT1.createValueGroup(properties(Constants.AFFINE));      // Initialized to identity.
-                parameters.parameter(Constants.NUM_COL).setValue(targetDim + 1);
-                parameters.parameter(Constants.NUM_ROW).setValue(targetDim + 1);
+                /*
+                 * TODO: instead than creating parameters for an identity operation, we should create the
+                 *       CoordinateOperation directly from the MathTransform created by mtFactory below.
+                 *       The intend if to get the correct OperationMethod, which should not be "Affine"
+                 *       if there is a CS type change.
+                 */
+                parameters = Affine.identity(targetDim);
                 /*
                  * createCoordinateSystemChange(…) needs the ellipsoid associated to the ellipsoidal coordinate system,
                  * if any. If none or both coordinate systems are ellipsoidal, then the ellipsoid will be ignored (see
@@ -947,10 +961,13 @@ public class CoordinateOperationFinder e
          * trivial operations.
          */
         CoordinateOperation main = null;
-        final boolean isAxisChange1 = (step1.getName() == AXIS_CHANGES);
-        final boolean isAxisChange2 = (step2.getName() == AXIS_CHANGES);
+        final boolean isAxisChange1 = canHide(step1.getName());
+        final boolean isAxisChange2 = canHide(step2.getName());
         if (isAxisChange1 && isAxisChange2 && isAffine(step1) && isAffine(step2)) {
             main = step2;                                           // Arbitrarily take the last step.
+            if (main.getName() == IDENTITY && step1.getName() != IDENTITY) {
+                main = step1;
+            }
         } else {
             if (isAxisChange1 && mt1.getSourceDimensions() == mt1.getTargetDimensions()) main = step2;
             if (isAxisChange2 && mt2.getSourceDimensions() == mt2.getTargetDimensions()) main = step1;
@@ -1003,8 +1020,8 @@ public class CoordinateOperationFinder e
         if (isIdentity(step1)) return concatenate(step2, step3);
         if (isIdentity(step2)) return concatenate(step1, step3);
         if (isIdentity(step3)) return concatenate(step1, step2);
-        if (step1.getName() == AXIS_CHANGES) return concatenate(concatenate(step1, step2), step3);
-        if (step3.getName() == AXIS_CHANGES) return concatenate(step1, concatenate(step2, step3));
+        if (canHide(step1.getName())) return concatenate(concatenate(step1, step2), step3);
+        if (canHide(step3.getName())) return concatenate(step1, concatenate(step2, step3));
         final Map<String,?> properties = defaultName(step1.getSourceCRS(), step3.getTargetCRS());
         return factory.createConcatenatedOperation(properties, step1, step2, step3);
     }
@@ -1028,7 +1045,22 @@ public class CoordinateOperationFinder e
      * are usually datum shift and must be visible.
      */
     private static boolean isIdentity(final CoordinateOperation operation) {
-        return (operation == null) || ((operation instanceof Conversion) && operation.getMathTransform().isIdentity());
+        if (operation == null) {
+            return true;
+        }
+        if ((operation instanceof Conversion) && operation.getMathTransform().isIdentity()) {
+            return CoordinateOperations.wrapAroundChanges(operation).isEmpty();
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if a coordinate operation of the given name can be hidden
+     * in the list of operations. Note that the {@code MathTransform} will still take
+     * the operation in account however.
+     */
+    private static boolean canHide(final Identifier id) {
+        return (id == AXIS_CHANGES) || (id == IDENTITY);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -113,7 +113,7 @@ class CoordinateOperationRegistry {
     /**
      * The identifier for an identity operation.
      */
-    private static final Identifier IDENTITY = createIdentifier(Vocabulary.Keys.Identity);
+    static final Identifier IDENTITY = createIdentifier(Vocabulary.Keys.Identity);
 
     /**
      * The identifier for conversion using an affine transform for axis swapping and/or unit conversions.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -52,7 +52,7 @@ import static org.apache.sis.util.Utilit
  * reference system associated with the concatenated operation.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.6
  * @module
  */
@@ -113,18 +113,36 @@ final class DefaultConcatenatedOperation
             throw new IllegalArgumentException(Errors.getResources(properties).getString(
                     Errors.Keys.TooFewOccurrences_2, 2, CoordinateOperation.class));
         }
+        initialize(properties, operations, mtFactory);
+        checkDimensions(properties);
+    }
+
+    /**
+     * Initializes the {@link #sourceCRS}, {@link #targetCRS} and {@link #operations} fields.
+     * If the source or target CRS is already non-null (which may happen on JAXB unmarshalling),
+     * leaves that CRS unchanged.
+     *
+     * @param  properties   the properties specified at construction time, or {@code null} if unknown.
+     * @param  operations   the operations to concatenate.
+     * @param  mtFactory    the math transform factory to use, or {@code null} for not performing concatenation.
+     * @throws FactoryException if the factory can not concatenate the math transforms.
+     */
+    private void initialize(final Map<String,?>         properties,
+                            final CoordinateOperation[] operations,
+                            final MathTransformFactory  mtFactory)
+            throws FactoryException
+    {
         final List<CoordinateOperation> flattened = new ArrayList<>(operations.length);
-        initialize(properties, operations, flattened, mtFactory,
-                (coordinateOperationAccuracy == null), (domainOfValidity == null));
+        final CoordinateReferenceSystem crs = initialize(properties, operations, flattened, mtFactory,
+                (sourceCRS == null), (coordinateOperationAccuracy == null), (domainOfValidity == null));
+        if (targetCRS == null) {
+            targetCRS = crs;
+        }
         /*
          * At this point we should have flattened.size() >= 2, except if some operations
          * were omitted because their associated math transform were identity operation.
          */
-        operations      = flattened.toArray(new CoordinateOperation[flattened.size()]);
-        this.operations = UnmodifiableArrayList.wrap(operations);
-        this.sourceCRS  = operations[0].getSourceCRS();
-        this.targetCRS  = operations[operations.length - 1].getTargetCRS();
-        checkDimensions(properties);
+        this.operations = UnmodifiableArrayList.wrap(flattened.toArray(new CoordinateOperation[flattened.size()]));
     }
 
     /**
@@ -162,17 +180,20 @@ final class DefaultConcatenatedOperation
      * @param  operations   the operations to concatenate.
      * @param  flattened    the destination list in which to add the {@code SingleOperation} instances.
      * @param  mtFactory    the math transform factory to use, or {@code null} for not performing concatenation.
+     * @param  setSource    {@code true} for setting the {@link #sourceCRS} on the very first CRS (regardless if null or not).
      * @param  setAccuracy  {@code true} for setting the {@link #coordinateOperationAccuracy} field.
      * @param  setDomain    {@code true} for setting the {@link #domainOfValidity} field.
+     * @return the last target CRS, regardless if null or not.
      * @throws FactoryException if the factory can not concatenate the math transforms.
      */
-    private void initialize(final Map<String,?>             properties,
-                            final CoordinateOperation[]     operations,
-                            final List<CoordinateOperation> flattened,
-                            final MathTransformFactory      mtFactory,
-                            boolean                         setAccuracy,
-                            boolean                         setDomain)
-            throws FactoryException
+    private CoordinateReferenceSystem initialize(
+            final Map<String,?>             properties,
+            final CoordinateOperation[]     operations,
+            final List<CoordinateOperation> flattened,
+            final MathTransformFactory      mtFactory,
+            boolean                         setSource,
+            boolean                         setAccuracy,
+            boolean                         setDomain) throws FactoryException
     {
         CoordinateReferenceSystem previous = null;
         for (int i=0; i<operations.length; i++) {
@@ -182,17 +203,19 @@ final class DefaultConcatenatedOperation
              * Verify consistency of user argument: for each coordinate operation, the number of dimensions of the
              * source CRS shall be equals to the number of dimensions of the target CRS in the previous operation.
              */
-            if (previous != null) {
-                final CoordinateReferenceSystem next = op.getSourceCRS();
-                if (next != null) {
-                    final int dim1 = previous.getCoordinateSystem().getDimension();
-                    final int dim2 = next.getCoordinateSystem().getDimension();
-                    if (dim1 != dim2) {
-                        throw new IllegalArgumentException(Errors.getResources(properties).getString(
-                                Errors.Keys.MismatchedDimension_3, "operations[" + i + "].sourceCRS", dim1, dim2));
-                    }
+            final CoordinateReferenceSystem next = op.getSourceCRS();
+            if (previous != null && next != null) {
+                final int dim1 = previous.getCoordinateSystem().getDimension();
+                final int dim2 = next.getCoordinateSystem().getDimension();
+                if (dim1 != dim2) {
+                    throw new IllegalArgumentException(Errors.getResources(properties).getString(
+                            Errors.Keys.MismatchedDimension_3, "operations[" + i + "].sourceCRS", dim1, dim2));
                 }
             }
+            if (setSource) {
+                setSource = false;
+                sourceCRS = next;                                               // Take even if null.
+            }
             previous = op.getTargetCRS();                                       // For next iteration cycle.
             /*
              * Now that we have verified the CRS dimensions, we should be able to concatenate the transforms.
@@ -207,11 +230,11 @@ final class DefaultConcatenatedOperation
                 final List<? extends CoordinateOperation> children = ((ConcatenatedOperation) op).getOperations();
                 @SuppressWarnings("SuspiciousToArrayCall")
                 final CoordinateOperation[] asArray = children.toArray(new CoordinateOperation[children.size()]);
-                initialize(properties, asArray, flattened, (step == null) ? mtFactory : null, setAccuracy, setDomain);
+                initialize(properties, asArray, flattened, (step == null) ? mtFactory : null, false, setAccuracy, setDomain);
             } else if (!step.isIdentity()) {
                 flattened.add(op);
             }
-            if (mtFactory != null) {
+            if (mtFactory != null && step != null) {
                 transform = (transform != null) ? mtFactory.createConcatenatedTransform(transform, step) : step;
             }
             /*
@@ -248,6 +271,7 @@ final class DefaultConcatenatedOperation
                 }
             }
         }
+        return previous;
     }
 
     /**
@@ -388,7 +412,6 @@ final class DefaultConcatenatedOperation
      * Returns the operations to marshal. We use this private methods instead than annotating
      * {@link #getOperations()} in order to force JAXB to invoke the setter method on unmarshalling.
      */
-    @SuppressWarnings("SuspiciousToArrayCall")
     @XmlElement(name = "coordOperation", required = true)
     private CoordinateOperation[] getSteps() {
         final List<? extends CoordinateOperation> operations = getOperations();
@@ -399,9 +422,6 @@ final class DefaultConcatenatedOperation
      * Invoked by JAXB for setting the operations.
      */
     private void setSteps(final CoordinateOperation[] steps) throws FactoryException {
-        final List<CoordinateOperation> flattened = new ArrayList<>(steps.length);
-        initialize(null, steps, flattened, DefaultFactories.forBuildin(MathTransformFactory.class),
-                (coordinateOperationAccuracy == null), (domainOfValidity == null));
-        operations = UnmodifiableArrayList.wrap(flattened.toArray(new CoordinateOperation[flattened.size()]));
+        initialize(null, steps, DefaultFactories.forBuildin(MathTransformFactory.class));
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.ServiceLoader;
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
@@ -44,6 +45,8 @@ import org.apache.sis.internal.util.Coll
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.referencing.LazySet;
 import org.apache.sis.referencing.CRS;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
@@ -676,6 +679,13 @@ next:   for (int i=components.size(); --
     public CoordinateOperation createConcatenatedOperation(final Map<String,?> properties,
             final CoordinateOperation... operations) throws FactoryException
     {
+        /*
+         * If the user specified a single operation, there is no need to create a ConcatenatedOperation;
+         * the operation to return will be the specified one. The metadata given in argument are ignored
+         * on the assumption that the single operation has more complete metadata (in particular an EPSG
+         * code, in which case we do not want to modify any other metadata in order to stay compliant
+         * with EPSG definition).
+         */
         if (operations != null && operations.length == 1) {
             return operations[0];
         }
@@ -688,14 +698,39 @@ next:   for (int i=components.size(); --
         /*
          * Verifies again the number of single operations.  We may have a singleton if some operations
          * were omitted because their associated math transform were identity. This happen for example
-         * if a "Geographic 3D to 2D conversion" as been redimensioned to a "3D to 3D" operation.
+         * if a "Geographic 3D to 2D conversion" has been redimensioned to a "3D to 3D" operation.
          */
         final List<? extends CoordinateOperation> co = op.getOperations();
-        if (co.size() == 1) {
-            assert op.getMathTransform().equals(co.get(0).getMathTransform()) : op;
-            return co.get(0);
+        if (co.size() != 1) {
+            return pool.unique(op);
         }
-        return pool.unique(op);
+        final CoordinateOperation single = co.get(0);
+        assert op.getMathTransform().equals(single.getMathTransform()) : op;
+        if (!Objects.equals(single.getSourceCRS(), op.getSourceCRS()) ||
+            !Objects.equals(single.getTargetCRS(), op.getTargetCRS()))
+        {
+            /*
+             * The CRS of the single operation may be different than the CRS of the concatenated operation
+             * if the first or the last operation was an identity operation. It happens for example if the
+             * sole purpose of an operation step was to change the longitude range from [-180 … +180]° to
+             * [0 … 360]°: the MathTransform is identity (because Apache SIS does not handle those changes
+             * in MathTransform; we handle that elsewhere, for example in the Envelopes utility class),
+             * but omitting the transform should not cause the lost of the CRS with desired longitude range.
+             */
+            if (single instanceof SingleOperation) {
+                final Map<String,Object> merge = new HashMap<String,Object>(
+                        IdentifiedObjects.getProperties(single, CoordinateOperation.IDENTIFIERS_KEY));
+                merge.put(ReferencingServices.PARAMETERS_KEY, ((SingleOperation) single).getParameterValues());
+                if (single instanceof AbstractIdentifiedObject) {
+                    merge.put(ReferencingServices.OPERATION_TYPE_KEY, ((AbstractIdentifiedObject) single).getInterface());
+                }
+                merge.putAll(properties);
+                return createSingleOperation(merge, op.getSourceCRS(), op.getTargetCRS(),
+                        AbstractCoordinateOperation.getInterpolationCRS(op),
+                        ((SingleOperation) single).getMethod(), single.getMathTransform());
+            }
+        }
+        return single;
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MathTransformContext.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MathTransformContext.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MathTransformContext.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MathTransformContext.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -18,6 +18,8 @@ package org.apache.sis.referencing.opera
 
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Matrix;
@@ -102,7 +104,7 @@ final class MathTransformContext extends
                 } else {
                     matrix = cm.multiply(rot);                  // Apply the rotation before normalization.
                 }
-            } else {
+            } else if (cs == null || cs instanceof EllipsoidalCS || cs instanceof SphericalCS) {
                 final Double value = rotation;
                 if (inverse) {
                     cm.convertBefore(0, null, value);           // Longitude is the first axis in normalized CS.
@@ -110,6 +112,8 @@ final class MathTransformContext extends
                     cm.convertAfter(0, null, value);
                 }
                 matrix = cm;
+            } else {
+                throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getName()));
             }
         }
         return matrix;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -317,7 +317,7 @@ public abstract class AbstractMathTransf
      *         double[] ordinates = Arrays.copyOfRange(srcPts, srcOff, srcOff + getSourceDimensions());
      *         derivative = this.derivative(new GeneralDirectPosition(ordinates));
      *     }
-     *     this.transform(srcPts, srcOff, dstPts, dstOff, 1);  // May overwrite srcPts.
+     *     this.transform(srcPts, srcOff, dstPts, dstOff, 1);                   // May overwrite srcPts.
      *     return derivative;
      * }
      *

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -153,7 +153,11 @@ public class MolodenskyTransform extends
         super(source, isSource3D, target, isTarget3D, tX, tY, tZ, null, isAbridged,
                 isAbridged ? AbridgedMolodensky.PARAMETERS : Molodensky.PARAMETERS);
         if (!isSource3D && !isTarget3D) {
-            inverse = new MolodenskyTransform2D(this, source, target);
+            if (isAbridged && tX == 0 && tY == 0 && tZ == 0) {
+                inverse = new AbridgedMolodenskyTransform2D(this, source, target);
+            } else {
+                inverse = new MolodenskyTransform2D(this, source, target);
+            }
         } else {
             inverse = new MolodenskyTransform(this, source, target);
         }
@@ -226,7 +230,11 @@ public class MolodenskyTransform extends
     {
         final MolodenskyTransform tr;
         if (!isSource3D && !isTarget3D) {
-            tr = new MolodenskyTransform2D(source, target, tX, tY, tZ, isAbridged);
+            if (isAbridged && tX == 0 && tY == 0 && tZ == 0) {
+                tr = new AbridgedMolodenskyTransform2D(source, target);
+            } else {
+                tr = new MolodenskyTransform2D(source, target, tX, tY, tZ, isAbridged);
+            }
         } else {
             tr = new MolodenskyTransform(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged);
         }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -33,7 +33,7 @@ import org.opengis.referencing.operation
  * @since   0.7
  * @module
  */
-final class MolodenskyTransform2D extends MolodenskyTransform implements MathTransform2D {
+class MolodenskyTransform2D extends MolodenskyTransform implements MathTransform2D {
     /**
      * Serial number for compatibility with different versions.
      */
@@ -52,9 +52,9 @@ final class MolodenskyTransform2D extend
     /**
      * Constructs the inverse of a 2D transform.
      *
-     * @param inverse The transform for which to create the inverse.
-     * @param source  The source ellipsoid of the given {@code inverse} transform.
-     * @param target  The target ellipsoid of the given {@code inverse} transform.
+     * @param inverse  the transform for which to create the inverse.
+     * @param source   the source ellipsoid of the given {@code inverse} transform.
+     * @param target   the target ellipsoid of the given {@code inverse} transform.
      */
     MolodenskyTransform2D(final MolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) {
         super(inverse, source, target);

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/AbstractEnvelopeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/AbstractEnvelopeTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/AbstractEnvelopeTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/AbstractEnvelopeTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -19,8 +19,8 @@ package org.apache.sis.geometry;
 import java.awt.geom.Rectangle2D;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
-import org.opengis.referencing.crs.GeographicCRS;
-import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.referencing.crs.DefaultGeographicCRS;
+import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -36,7 +36,7 @@ import static org.apache.sis.test.Refere
  * Various implementations are used for each test.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.4
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -51,7 +51,7 @@ public final strictfp class AbstractEnve
     /**
      * The coordinate reference system used for the tests.
      */
-    static final GeographicCRS WGS84 = CommonCRS.WGS84.normalizedGeographic();
+    static final DefaultGeographicCRS WGS84 = HardCodedCRS.WGS84;
 
     /**
      * Creates an envelope of the given type. The type shall be one of the

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/EnvelopesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/EnvelopesTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/EnvelopesTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/EnvelopesTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -19,14 +19,18 @@ package org.apache.sis.geometry;
 import java.util.Collections;
 import org.opengis.geometry.Envelope;
 import org.opengis.util.FactoryException;
+import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.MathTransform2D;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.transform.MathTransformWrapper;
 import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
-import org.apache.sis.referencing.operation.transform.MathTransformWrapper;
+import org.apache.sis.referencing.cs.AxesConvention;
+import org.apache.sis.referencing.CRS;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.DependsOnMethod;
 import org.junit.Test;
 
 import static org.apache.sis.test.ReferencingAssert.*;
@@ -171,4 +175,56 @@ public final strictfp class EnvelopesTes
         assertEquals( -80, env2D.getMinimum(1), 0);
         assertEquals(  80, env2D.getMaximum(1), 0);
     }
+
+    /**
+     * Tests a transformation from a three-dimensional CRS where the range of longitude axis is changed.
+     * This is the same test than {@link #testAxisRangeChange()} but using a compound CRS as the source.
+     * Internally, this results in the concatenation of transforms. We want to ensure that information
+     * about axis range changes are not lost in this process.
+     *
+     * @throws FactoryException if an error occurred while creating the operation.
+     * @throws TransformException if an error occurred while transforming the envelope.
+     *
+     * @since 0.8
+     */
+    @Test
+    @DependsOnMethod("testAxisRangeChange")
+    public void testAxisRangeChange3D() throws FactoryException, TransformException {
+        testAxisRangeChange3D(HardCodedCRS.WGS84);
+    }
+
+    /**
+     * Tests a change of longitude axis range together with change of ellipsoid. This is the same test
+     * than {@link #testAxisRangeChange3D()} with an additional complexity: a change of ellipsoid.
+     * This causes the execution of different code branches in {@code ConcatenatedOperation} creation.
+     *
+     * @throws FactoryException if an error occurred while creating the operation.
+     * @throws TransformException if an error occurred while transforming the envelope.
+     *
+     * @since 0.8
+     */
+    @Test
+    @DependsOnMethod("testAxisRangeChange3D")
+    public void testAxisRangeChangeWithDatumShift() throws FactoryException, TransformException {
+        testAxisRangeChange3D(HardCodedCRS.SPHERE);
+    }
+
+    /**
+     * Implementation of {@link #testAxisRangeChange3D()} and {@link #testAxisRangeChangeWithDatumShift()}.
+     */
+    private void testAxisRangeChange3D(final GeographicCRS targetCRS) throws FactoryException, TransformException {
+        final GeneralEnvelope envelope  = new GeneralEnvelope(new double[] { -0.5, -90, 1000},
+                                                              new double[] {354.5, +90, 1002});
+        envelope.setCoordinateReferenceSystem(CRS.compound(
+                HardCodedCRS.WGS84.forConvention(AxesConvention.POSITIVE_RANGE), HardCodedCRS.TIME));
+        final GeneralEnvelope expected = createFromExtremums(targetCRS, -0.5, -90, -5.5, 90);
+        assertEnvelopeEquals(expected, Envelopes.transform(envelope, targetCRS), STRICT, STRICT);
+        /*
+         * When the envelope to transform span the full longitude range,
+         * target envelope should unconditionally be [-180 … +180]°.
+         */
+        envelope.setRange(0, -0.5, 359.5);
+        expected.setRange(0, -180, 180);
+        assertEnvelopeEquals(expected, Envelopes.transform(envelope, targetCRS), STRICT, STRICT);
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/GeneralEnvelopeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/GeneralEnvelopeTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/GeneralEnvelopeTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/GeneralEnvelopeTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -39,7 +39,7 @@ import static org.apache.sis.geometry.Ab
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 0.5
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -97,7 +97,7 @@ public strictfp class GeneralEnvelopeTes
             final double xLower, final double ymin, final double xUpper, final double ymax)
     {
         final double xmin, xmax;
-        if (MathFunctions.isNegative(xUpper - xLower)) { // Check for anti-meridian spanning.
+        if (MathFunctions.isNegative(xUpper - xLower)) {                // Check for anti-meridian spanning.
             xmin = -180;
             xmax = +180;
         } else {
@@ -131,25 +131,24 @@ public strictfp class GeneralEnvelopeTes
     private static void assertIntersectEquals(final GeneralEnvelope e1, final GeneralEnvelope e2,
             final double xmin, final double ymin, final double xmax, final double ymax)
     {
-        final boolean isEmpty = !(((xmax - xmin) * (ymax - ymin)) != 0);        // Use ! for catching NaN.
         final Envelope2D r1 = new Envelope2D(e1);
         final Envelope2D r2 = new Envelope2D(e2);
         final Envelope2D ri = r1.createIntersection(r2);
-        assertEquals("isEmpty", isEmpty, r1.isEmpty());
+        assertFalse("isEmpty", r1.isEmpty());
         assertEnvelopeEquals(ri, xmin, ymin, xmax, ymax);
         assertEquals("Interchanged arguments.", ri, r2.createIntersection(r1));
 
         // Compares with GeneralEnvelope.
         final GeneralEnvelope ei = new GeneralEnvelope(e1);
         ei.intersect(e2);
-        assertEquals("isEmpty", isEmpty, e1.isEmpty());
+        assertFalse("isEmpty", e1.isEmpty());
         assertEnvelopeEquals(ei, xmin, ymin, xmax, ymax);
         assertTrue("Using GeneralEnvelope.", ei.equals(ri, STRICT, false));
 
         // Interchanges arguments.
         ei.setEnvelope(e2);
         ei.intersect(e1);
-        assertEquals("isEmpty", isEmpty, e1.isEmpty());
+        assertFalse("isEmpty", e1.isEmpty());
         assertEnvelopeEquals(ei, xmin, ymin, xmax, ymax);
         assertTrue("Using GeneralEnvelope.", ei.equals(ri, STRICT, false));
     }
@@ -233,7 +232,7 @@ public strictfp class GeneralEnvelopeTes
         //  └──────────┘
         e1.setEnvelope(20, -20,  80, 12);
         e2.setEnvelope(40, -10, 100, 30);
-        final double ymin=-10, ymax=12; // Will not change anymore
+        final double ymin=-10, ymax=12;                         // Will not change anymore
         assertIntersectEquals(e1, e2, 40, ymin, 80, ymax);
         //  ────┐  ┌────
         //  ──┐ │  │ ┌──
@@ -272,6 +271,20 @@ public strictfp class GeneralEnvelopeTes
         //  ─────┘     └─────
         e2.setRange(0, 10, 90);
         assertIntersectEquals(e1, e2, NaN, ymin, NaN, ymax);
+        //  ────────┬────────
+        //        ┌─┼────┐
+        //        └─┼────┘
+        //  ────────┴────────
+        e1.setRange(0, 0.0, -0.0);
+        e2.setRange(0, -10,   30);
+        assertIntersectEquals(e1, e2, -10, ymin, 30, ymax);
+        //  ┌───────────────┐
+        //  │               │
+        //  │               │
+        //  └───────────────┘
+        e1.setRange(0, 0.0, -0.0);
+        e2.setRange(0, 0.0, -0.0);
+        assertIntersectEquals(e1, e2, 0.0, ymin, -0.0, ymax);
 
         // Post-test verification, mostly for SubEnvelope.
         verifyInvariants(e1);

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/Shapes2DTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/Shapes2DTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/Shapes2DTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/Shapes2DTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -17,6 +17,7 @@
 package org.apache.sis.geometry;
 
 import java.awt.geom.Rectangle2D;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.MathTransform2D;
@@ -42,6 +43,12 @@ public final strictfp class Shapes2DTest
      */
     @Override
     Rectangle2D createFromExtremums(CoordinateReferenceSystem crs, double xmin, double ymin, double xmax, double ymax) {
+        if (xmin > xmax) {
+            // This implementation does not support spanning anti-meridian.
+            final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(0);
+            xmin = axis.getMinimumValue();
+            xmax = axis.getMaximumValue();
+        }
         return new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin);
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -28,7 +28,10 @@ import org.opengis.util.FactoryException
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.operation.DefaultConversion;
+import org.apache.sis.referencing.operation.HardCodedConversions;
+import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -82,6 +85,12 @@ public abstract strictfp class Transform
     abstract void assertGeometryEquals(G expected, G actual, double tolx, double toly);
 
     /**
+     * Allows sub-classing in same package only.
+     */
+    TransformTestCase() {
+    }
+
+    /**
      * Tests the transformation of an envelope or rectangle. This is a relatively simple test case
      * working in the two-dimensional space only, with a coordinate operation of type "conversion"
      * (not a "transformation") and with no need to adjust for poles.
@@ -212,6 +221,29 @@ public abstract strictfp class Transform
     }
 
     /**
+     * Tests transform of an envelope over the ±180° limit. The Mercator projection used in this test
+     * is not expected to wrap the longitude around Earth when using only the {@code MathTransform}.
+     * However when the target CRS is known, then "wrap around" should be applied.
+     *
+     * @throws TransformException if an error occurred while transforming the envelope.
+     *
+     * @since 0.8
+     */
+    @Test
+    @DependsOnMethod("testTransform")
+    public final void testTransformOverAntiMeridian() throws TransformException {
+        final ProjectedCRS  sourceCRS  = HardCodedConversions.mercator();
+        final GeographicCRS targetCRS  = sourceCRS.getBaseCRS();
+        final Conversion    conversion = inverse(sourceCRS.getConversionFromBase());
+        final G expected  = createFromExtremums(targetCRS, 179, 40, 181, 50);
+        final G rectangle = createFromExtremums(sourceCRS,
+                19926188.852, 4838471.398,                      // Computed by SIS (not validated by external authority).
+                20148827.834, 6413524.594);
+        final G actual = transform(conversion, rectangle);
+        assertGeometryEquals(expected, actual, ANGULAR_TOLERANCE, ANGULAR_TOLERANCE);
+    }
+
+    /**
      * Returns the inverse of the given conversion. This method is not strictly correct
      * since we reuse the properties (name, aliases, etc.) from the given conversion.
      * However those properties are not significant for the purpose of this test.
@@ -220,4 +252,22 @@ public abstract strictfp class Transform
         return new DefaultConversion(IdentifiedObjects.getProperties(conversion), conversion.getTargetCRS(),
                 conversion.getSourceCRS(), null, conversion.getMethod(), conversion.getMathTransform().inverse());
     }
+
+    /**
+     * Tests a transformation where only the range of longitude axis is changed.
+     *
+     * @throws FactoryException if an error occurred while creating the operation.
+     * @throws TransformException if an error occurred while transforming the envelope.
+     *
+     * @since 0.8
+     */
+    @Test
+    public final void testAxisRangeChange() throws FactoryException, TransformException {
+        final GeographicCRS sourceCRS = HardCodedCRS.WGS84;
+        final GeographicCRS targetCRS = HardCodedCRS.WGS84.forConvention(AxesConvention.POSITIVE_RANGE);
+        final G rectangle = createFromExtremums(sourceCRS, -178, -70, 165, 80);
+        final G expected  = createFromExtremums(targetCRS,  182, -70, 165, 80);
+        final G actual    = transform(CRS.findOperation(sourceCRS, targetCRS, null), rectangle);
+        assertGeometryEquals(expected, actual, STRICT, STRICT);
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -19,7 +19,6 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Arrays;
-import java.util.Collections;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -39,7 +38,6 @@ import org.apache.sis.util.Utilities;
 // Test imports
 import org.apache.sis.referencing.operation.HardCodedConversions;
 import org.apache.sis.referencing.crs.HardCodedCRS;
-import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -288,9 +286,7 @@ public final strictfp class CRSTest exte
      */
     @Test
     public void testComponentsOfProjectedCRS() {
-        final ProjectedCRS volumetric = new DefaultProjectedCRS(Collections.singletonMap(ProjectedCRS.NAME_KEY, "3D"),
-                HardCodedCRS.WGS84_3D, HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED_3D);
-
+        final ProjectedCRS volumetric = HardCodedConversions.mercator3D();
         assertFalse("isHorizontalCRS", CRS.isHorizontalCRS(volumetric));
         assertNull("getTemporalComponent", CRS.getTemporalComponent(volumetric));
         assertNull("getVerticalComponent", CRS.getVerticalComponent(volumetric, false));

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/HardCodedConversions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/HardCodedConversions.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/HardCodedConversions.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/HardCodedConversions.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -16,9 +16,15 @@
  */
 package org.apache.sis.referencing.operation;
 
+import java.util.Map;
 import java.util.Collections;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
 import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.internal.referencing.provider.Mercator1SP;
+import org.apache.sis.referencing.crs.DefaultProjectedCRS;
+import org.apache.sis.referencing.crs.HardCodedCRS;
+import org.apache.sis.referencing.cs.HardCodedCS;
 
 
 /**
@@ -46,4 +52,52 @@ public final strictfp class HardCodedCon
      */
     private HardCodedConversions() {
     }
+
+    /**
+     * A two-dimensional Mercator projection using the WGS84 datum.
+     * This CRS uses (<var>easting</var>, <var>northing</var>) ordinates in metres.
+     * The base CRS uses (<var>longitude</var>, <var>latitude</var>) axes
+     * and the prime meridian is Greenwich.
+     *
+     * <p>This CRS is equivalent to {@code EPSG:3395} except for base CRS axis order,
+     * since EPSG puts latitude before longitude.</p>
+     *
+     * @return two-dimensional Mercator projection.
+     */
+    public static DefaultProjectedCRS mercator() {
+        return new DefaultProjectedCRS(name("Mercator"),
+                HardCodedCRS.WGS84, HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED);
+    }
+
+    /**
+     * A three-dimensional Mercator projection using the WGS84 datum.
+     * This CRS uses (<var>easting</var>, <var>northing</var>, <var>height</var>) ordinates in metres.
+     * The base CRS uses (<var>longitude</var>, <var>latitude</var>, <var>height</var>) axes
+     * and the prime meridian is Greenwich.
+     *
+     * @return three-dimensional Mercator projection.
+     */
+    public static DefaultProjectedCRS mercator3D() {
+        return new DefaultProjectedCRS(name("Mercator 3D"),
+                HardCodedCRS.WGS84_3D, HardCodedConversions.MERCATOR, HardCodedCS.PROJECTED_3D);
+    }
+
+    /**
+     * A two- or three-dimensional Mercator projection using the given base CRS.
+     * This CRS uses (<var>easting</var>, <var>northing</var>) ordinates in metres.
+     *
+     * @param  baseCRS  the two- or three-dimensional base CRS.
+     * @return two- or three-dimensional Mercator projection.
+     */
+    public static DefaultProjectedCRS mercator(final GeographicCRS baseCRS) {
+        return new DefaultProjectedCRS(name("Mercator (other)"), baseCRS, HardCodedConversions.MERCATOR,
+                baseCRS.getCoordinateSystem().getDimension() == 3 ? HardCodedCS.PROJECTED_3D : HardCodedCS.PROJECTED);
+    }
+
+    /**
+     * Puts the given name in a property map CRS constructors.
+     */
+    private static Map<String,?> name(final String name) {
+        return Collections.singletonMap(ProjectedCRS.NAME_KEY, name);
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -314,6 +314,7 @@ public abstract strictfp class MathTrans
 
     /**
      * Generates random numbers that can be used for the current transform.
+     * The number of dimensions is given by {@code transform.getSourceDimensions()}.
      *
      * @param  domain   the domain of the numbers to be generated.
      * @param  propNaN  approximative percentage of NaN values as a fraction between 0 and 1, or 0 if none.

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -22,6 +22,7 @@ import java.awt.geom.RectangularShape;
 import java.awt.geom.AffineTransform;
 import javax.measure.Unit;
 import org.opengis.geometry.Envelope;
+import org.opengis.geometry.DirectPosition;
 import org.opengis.metadata.Identifier;
 import org.opengis.parameter.GeneralParameterValue;
 import org.opengis.parameter.ParameterDescriptor;
@@ -54,7 +55,7 @@ import org.apache.sis.internal.jdk8.JDK8
  * from other modules and libraries.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -284,15 +285,19 @@ public strictfp class ReferencingAssert
     public static void assertEnvelopeEquals(final Envelope expected, final Envelope actual, final double... tolerances) {
         final int dimension = expected.getDimension();
         assertEquals("dimension", dimension, actual.getDimension());
+        final DirectPosition expectedLower = expected.getLowerCorner();
+        final DirectPosition expectedUpper = expected.getUpperCorner();
+        final DirectPosition actualLower   = actual  .getLowerCorner();
+        final DirectPosition actualUpper   = actual  .getUpperCorner();
         double tolerance = 0;
         for (int i=0; i<dimension; i++) {
             if (i < tolerances.length) {
                 tolerance = tolerances[i];
             }
-            if (abs(expected.getMinimum(i) - actual.getMinimum(i)) > tolerance ||
-                abs(expected.getMaximum(i) - actual.getMaximum(i)) > tolerance)
+            if (abs(expectedLower.getOrdinate(i) - actualLower.getOrdinate(i)) > tolerance ||
+                abs(expectedUpper.getOrdinate(i) - actualUpper.getOrdinate(i)) > tolerance)
             {
-                fail("Envelopes are not equal:\n"
+                fail("Envelopes are not equal in dimension " + i + ":\n"
                         + "expected " + Envelopes.toString(expected) + "\n"
                         + " but got " + Envelopes.toString(actual));
             }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -125,6 +125,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.transform.ContextualParametersTest.class,
     org.apache.sis.referencing.operation.transform.EllipsoidToCentricTransformTest.class,
     org.apache.sis.referencing.operation.transform.MolodenskyTransformTest.class,
+    org.apache.sis.referencing.operation.transform.AbridgedMolodenskyTransformTest.class,
     org.apache.sis.referencing.operation.transform.SphericalToCartesianTest.class,
     org.apache.sis.referencing.operation.transform.CartesianToSphericalTest.class,
     org.apache.sis.referencing.operation.transform.PolarToCartesianTest.class,
@@ -221,6 +222,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.cs.CodesTest.class,
     org.apache.sis.referencing.CRSTest.class,
     org.apache.sis.internal.referencing.DefinitionVerifierTest.class,
+    org.apache.sis.internal.referencing.CoordinateOperationsTest.class,
 
     // Coordinate operation finders are last, since they need everything else.
     org.apache.sis.referencing.operation.CoordinateOperationRegistryTest.class,

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -37,6 +37,7 @@ import javax.management.InstanceAlreadyE
 import java.lang.management.ManagementFactory;
 
 import org.apache.sis.setup.About;
+import org.apache.sis.util.Configuration;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.resources.Messages;
@@ -83,6 +84,7 @@ public final class Supervisor extends St
      * and the MBean will not be registered. This method does not propagate the exception
      * because the MBean is not a mandatory part of SIS library.</p>
      */
+    @Configuration
     public static synchronized void register() {
         if (name == null) {
             name = ObjectName.WILDCARD;                         // In case of failure.
@@ -113,6 +115,7 @@ public final class Supervisor extends St
      *
      * @throws JMException if an error occurred during unregistration.
      */
+    @Configuration
     static synchronized void unregister() throws JMException {
         final ObjectName n = name;
         if (n != null) {

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -336,6 +336,8 @@ public final class CollectionsExt extend
      * @return a set containing the array elements, or {@code null} if the given array was null.
      *
      * @see Collections#unmodifiableSet(Set)
+     *
+     * @todo Consider replacing by {@code Set.of(...)} in JDK9.
      */
     @SafeVarargs
     @SuppressWarnings("fallthrough")

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -34,7 +34,8 @@ import org.apache.sis.util.ArgumentCheck
  * <p>This class is <strong>not</strong> thread-safe. Synchronizations (if wanted) are user's responsibility.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @author  Alexis Manin (Geomatys)
+ * @version 0.8
  *
  * @see org.apache.sis.math.Vector
  *
@@ -154,9 +155,12 @@ public class IntegerList extends Abstrac
      * the previous one, then the extra elements are initialized to 0.
      *
      * @param  size  the new size.
+     *
+     * @see #trimToSize()
      */
     public void resize(final int size) {
         ArgumentChecks.ensurePositive("size", size);
+        modCount++;
         if (size > this.size) {
             int base = this.size * bitCount;
             final int offset = base & OFFSET_MASK;
@@ -176,13 +180,14 @@ public class IntegerList extends Abstrac
 
     /**
      * Fills the list with the given value.
-     * Every existing values are overwritten from index 0 inclusive up to {@link #size} exclusive.
+     * Every existing values are overwritten from index 0 inclusive up to {@link #size()} exclusive.
      *
      * @param  value  the value to set.
      */
     @SuppressWarnings("fallthrough")
     public void fill(int value) {
         ArgumentChecks.ensureBetween("value", 0, mask, value);
+        modCount++;
         final long p;
         if (value == 0) {
             p = 0;                              // All bits set to 0.
@@ -210,6 +215,7 @@ public class IntegerList extends Abstrac
      */
     @Override
     public void clear() {
+        modCount++;
         size = 0;
     }
 
@@ -237,6 +243,7 @@ public class IntegerList extends Abstrac
      */
     public void addInt(final int value) throws IllegalArgumentException {
         ArgumentChecks.ensureBetween("value", 0, mask, value);
+        modCount++;
         final int last = size;
         final int length = length(++size);
         if (length > values.length) {
@@ -271,7 +278,8 @@ public class IntegerList extends Abstrac
 
     /**
      * Returns the element at the given index as the {@code int} primitive type.
-     * This argument does not check argument validity, since it is assumed already done.
+     * This argument does not check argument validity, since the verification is
+     * assumed already done.
      *
      * @param  index  the element index.
      * @return the value at the given index.
@@ -318,12 +326,14 @@ public class IntegerList extends Abstrac
     public void setInt(int index, int value) throws IndexOutOfBoundsException {
         ArgumentChecks.ensureValidIndex(size, index);
         ArgumentChecks.ensureBetween("value", 0, mask, value);
+        modCount++;
         setUnchecked(index, value);
     }
 
     /**
      * Sets the element at the given index as the {@code int} primitive type.
-     * This argument does not check argument validity, since it is assumed already done.
+     * This argument does not check argument validity, since the verification
+     * is assumed already done.
      *
      * @param  index  the element index.
      * @param  value  the value at the given index.
@@ -352,6 +362,7 @@ public class IntegerList extends Abstrac
     @Override
     public Integer remove(final int index) throws IndexOutOfBoundsException {
         final Integer old = get(index);
+        modCount++;
         removeRange(index, index+1);
         return old;
     }
@@ -364,6 +375,7 @@ public class IntegerList extends Abstrac
      */
     public int removeLast() throws NoSuchElementException {
         if (size != 0) {
+            modCount++;
             return getUnchecked(--size);
         }
         throw new NoSuchElementException();
@@ -423,7 +435,21 @@ public class IntegerList extends Abstrac
     }
 
     /**
+     * Invokes {@link #trimToSize()} before serialization in order to make the stream more compact.
+     *
+     * @param  out  the output stream where to serialize this list.
+     * @throws IOException if an I/O error occurred while writing.
+     */
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+        trimToSize();
+        out.defaultWriteObject();
+    }
+
+    /**
      * Trims the capacity of this list to be its current size.
+     *
+     * @see #size()
+     * @see #resize(int)
      */
     public void trimToSize() {
         values = ArraysExt.resize(values, length(size));
@@ -442,18 +468,8 @@ public class IntegerList extends Abstrac
         } catch (CloneNotSupportedException e) {
             throw new AssertionError(e);
         }
-        clone.values = clone.values.clone();
+        clone.values = Arrays.copyOf(values, length(size));
+        clone.modCount = 0;
         return clone;
     }
-
-    /**
-     * Invokes {@link #trimToSize()} before serialization in order to make the stream more compact.
-     *
-     * @param  out  the output stream where to serialize this list.
-     * @throws IOException if an I/O error occurred while writing.
-     */
-    private void writeObject(final ObjectOutputStream out) throws IOException {
-        trimToSize();
-        out.defaultWriteObject();
-    }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -42,7 +42,8 @@ import org.apache.sis.util.Classes;
  * Assertion methods used by the SIS project in addition of the JUnit and GeoAPI assertions.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @author  Alexis Manin (Geomatys)
+ * @version 0.8
  * @since   0.3
  * @module
  */

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/IntegerListTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/IntegerListTest.java?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/IntegerListTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/IntegerListTest.java [UTF-8] Fri Oct 27 12:31:45 2017
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.Random;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.TestUtilities;
@@ -34,61 +35,89 @@ import static org.apache.sis.test.Assert
  * Tests {@link IntegerList} implementations.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @author  Alexis Manin (Geomatys)
+ * @version 0.8
  * @since   0.7
  * @module
  */
 public final strictfp class IntegerListTest extends TestCase {
     /**
-     * The list of integers.
+     * The list of integers being tested.
      */
     private IntegerList list;
 
     /**
      * Writes values and read them again for making sure they are the expected ones.
+     * This method tests also split iterators.
      *
      * @param maximalValue  the maximal value allowed.
      */
     private void testReadWrite(final int maximalValue) {
         final Random random = TestUtilities.createRandomNumberGenerator();
-        final int length = 400;
-        // Use half the lenght as initial capacity in order to test dynamic resizing.
+        final int length = 350 + random.nextInt(101);
+        /*
+         * Use half the lenght as initial capacity in order to test dynamic resizing.
+         * Dynamic resizing should happen in one of the call to list.add(value) after
+         * about 200 values.
+         */
         list = new IntegerList(length / 2, maximalValue);
-        assertTrue(list.maximalValue() >= maximalValue);
+        assertTrue("maximalValue()", list.maximalValue() >= maximalValue);
         final List<Integer> copy = new ArrayList<>(length);
         for (int i=0; i<length; i++) {
-            assertEquals(i, list.size());
+            assertEquals("size()", i, list.size());
             final Integer value = nextInt(random, maximalValue);
-            assertTrue(copy.add(value));
-            assertTrue(list.add(value));
+            assertTrue("add(Integer)", copy.add(value));
+            assertTrue("add(Integer)", list.add(value));
         }
-        assertEquals(copy, list);
-        assertEquals(copy.hashCode(), list.hashCode());
+        assertEquals("Comparison with reference implementation", copy, list);
+        assertEquals("hashCode()", copy.hashCode(), list.hashCode());
         /*
-         * Overwrite 1/10 of the values.
+         * Overwrite about 1/10 of the values in both the tested IntegerList and the
+         * reference ArrayList. Then compare the IntegerList against the reference.
          */
-        for (int i=0; i<length; i+=10) {
+        for (int i=0; i<length; i += 8 + random.nextInt(5)) {
             final Integer value = nextInt(random, maximalValue);
             final Integer old = copy.set(i, value);
-            assertNotNull(old);
-            assertEquals(old, list.set(i, value));
+            assertNotNull("set(Integer)", old);
+            assertEquals ("set(Integer)", old, list.set(i, value));
         }
         for (int i=0; i<length; i++) {
-            assertEquals(String.valueOf(i), copy.get(i), list.get(i));
+            if (!copy.get(i).equals(list.get(i))) {
+                fail("Mismatched value at index " + i);
+            }
         }
-        assertEquals(copy, list);
-        assertEquals(copy.hashCode(), list.hashCode());
-        assertNotSame(list, assertSerializedEquals(list));
+        assertEquals("Comparison with reference implementation", copy, list);
+        assertEquals("hashCode()", copy.hashCode(), list.hashCode());
         /*
-         * Tests cloning and removal of values.
+         * Tests cloning and removal of values in a range of indices. The IntegerList.removeRange(…)
+         * method is invoked indirectly by subList(…).clear(). Again, we use ArrayList as a reference.
          */
-        final List<Integer> clone = list.clone();
-        assertEquals(copy, clone);
-        assertEquals(copy.remove(100), clone.remove(100));
-        assertEquals(copy, clone);
+        final IntegerList clone = list.clone();
+        assertEquals("clone()", copy, clone);
+        assertEquals("remove(int)", copy.remove(100), clone.remove(100));
+        assertEquals("remove(int)", copy, clone);
         copy .subList(128, 256).clear();
         clone.subList(128, 256).clear();
-        assertEquals(copy, clone);
+        assertEquals("After removeRange(…)", copy, clone);
+        /*
+         * Tests iterator on integers, with random removal of some elements during traversal.
+         */
+        final Iterator<Integer> it = clone.iterator();
+        final Iterator<Integer> itRef = copy.iterator();
+        while (itRef.hasNext()) {
+            assertTrue("hasNext()", it.hasNext());
+            assertEquals(itRef.next(), it.next());
+            if (random.nextInt(10) == 0) {
+                itRef.remove();
+                it.remove();
+            }
+        }
+        assertFalse("hasNext()", it.hasNext());
+        assertEquals("After remove()", copy, clone);
+        /*
+         * Verify that serialization and deserialization gives a new list with identical content.
+         */
+        assertNotSame("Serialization", list, assertSerializedEquals(list));
     }
 
     /**
@@ -107,15 +136,14 @@ public final strictfp class IntegerListT
      * already filled with random values prior this method call.
      */
     private void testFill(final int value) {
-        assertEquals(400, list.size());
         final Set<Integer> set = new HashSet<>();
         list.fill(value);
         set.addAll(list);
-        assertEquals(Collections.singleton(value), set);
+        assertEquals("fill(value)", Collections.singleton(value), set);
         list.fill(0);
         set.clear();
         set.addAll(list);
-        assertEquals(Collections.singleton(0), set);
+        assertEquals("fill(0)", Collections.singleton(0), set);
     }
 
     /**
@@ -160,14 +188,13 @@ public final strictfp class IntegerListT
     @Test
     public void test100() {
         testReadWrite(100);
-        assertEquals(400, list.size());
         final int old100 = list.getInt(100);
         list.resize(101);
-        assertEquals(old100, list.getInt(100));
+        assertEquals("getInt(last)", old100, list.getInt(100));
         list.resize(200);
-        assertEquals(200, list.size());
-        assertEquals(old100, list.getInt(100));
-        assertEquals(0, list.getInt(101));
+        assertEquals("size()",              200, list.size());
+        assertEquals("getInt(existing)", old100, list.getInt(100));
+        assertEquals("getInt(new)",           0, list.getInt(101));
         for (int i=101; i<200; i++) {
             assertEquals(0, list.getInt(i));
         }

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] Fri Oct 27 12:31:45 2017
@@ -3,6 +3,6 @@
 build.xml.data.CRC32=58e6b21c
 build.xml.script.CRC32=462eaba0
 build.xml.stylesheet.CRC32=28e38971@1.53.1.46
-nbproject/build-impl.xml.data.CRC32=0b3b5126
+nbproject/build-impl.xml.data.CRC32=371f012d
 nbproject/build-impl.xml.script.CRC32=1cb14af5
 nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml?rev=1813520&r1=1813519&r2=1813520&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml Fri Oct 27 12:31:45 2017
@@ -82,6 +82,7 @@
             <word>deserialized</word>
             <word>endianness</word>
             <word>geoidal</word>
+            <word>geospatial</word>
             <word>grayscale</word>
             <word>hectopascals</word>
             <word>initially</word>



Mime
View raw message