sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1740146 [2/7] - in /sis/branches/JDK7: ./ core/sis-feature/ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/main/java/org/apache/sis/internal/ core/sis-feature/src/main/java/org/apache/sis/internal/feature/ core...
Date Wed, 20 Apr 2016 13:49:35 GMT
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -86,6 +86,7 @@ import static java.util.Collections.sing
  *
  * @author  Rémi Eve (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @author  Johann Sorel (Geomatys)
  * @since   0.6
  * @version 0.7
  * @module
@@ -202,7 +203,7 @@ final class GeodeticObjectParser extends
         csFactory       = (CSFactory)    factories;
         datumFactory    = (DatumFactory) factories;
         referencing     = ReferencingServices.getInstance();
-        opFactory       = referencing.getCoordinateOperationFactory(defaultProperties, mtFactory);
+        opFactory       = referencing.getCoordinateOperationFactory(defaultProperties, mtFactory, crsFactory, csFactory);
         transliterator  = Transliterator.DEFAULT;
         usesCommonUnits = false;
         ignoreAxes      = false;
@@ -239,7 +240,7 @@ final class GeodeticObjectParser extends
         if (f != null) {
             opFactory = (CoordinateOperationFactory) f;
         } else {
-            opFactory = referencing.getCoordinateOperationFactory(null, mtFactory);
+            opFactory = referencing.getCoordinateOperationFactory(null, mtFactory, crsFactory, csFactory);
             factories.put(CoordinateOperationFactory.class, opFactory);
         }
     }
@@ -299,7 +300,7 @@ final class GeodeticObjectParser extends
                     else ex.addSuppressed(e);
                 }
                 if (verticalElements != null) {
-                    warning(null, null, Errors.formatInternational(Errors.Keys.CanNotAssignUnitToDimension_2,
+                    warning(null, (String) null, Errors.formatInternational(Errors.Keys.CanNotAssignUnitToDimension_2,
                             WKTKeywords.VerticalExtent, verticalElements.unit), ex);
                 }
             }
@@ -307,7 +308,7 @@ final class GeodeticObjectParser extends
             verticalElements = null;
             verticalCRS = null;
             axisOrder.clear();
-            properties.clear();     // for letting the garbage collector do its work.
+            properties.clear();                             // for letting the garbage collector do its work.
         }
         return object;
     }
@@ -337,6 +338,7 @@ final class GeodeticObjectParser extends
             (object = parseToWGS84          (FIRST, element       )) == null &&
             (object = parseVerticalDatum    (FIRST, element, false)) == null &&
             (object = parseTimeDatum        (FIRST, element       )) == null &&
+            (object = parseParametricDatum  (FIRST, element       )) == null &&
             (object = parseEngineeringDatum (FIRST, element, false)) == null &&
             (object = parseImageDatum       (FIRST, element       )) == null &&
             (object = parseOperation        (FIRST, element))        == null)
@@ -362,6 +364,7 @@ final class GeodeticObjectParser extends
             (crs = parseProjectedCRS   (FIRST, element, false))   == null &&
             (crs = parseVerticalCRS    (FIRST, element, false))   == null &&
             (crs = parseTimeCRS        (FIRST, element, false))   == null &&
+            (crs = parseParametricCRS  (FIRST, element, false))   == null &&
             (crs = parseEngineeringCRS (FIRST, element, false))   == null &&
             (crs = parseImageCRS       (FIRST, element))          == null &&
             (crs = parseCompoundCRS    (FIRST, element))          == null &&
@@ -704,7 +707,7 @@ final class GeodeticObjectParser extends
                                 new String[] {WKTKeywords.CS, type}, element.offset);
                     }
                 }
-                if (dimension <= 0 || dimension > 1000) {  // Arbitrary upper limit against badly formed CS.
+                if (dimension <= 0 || dimension > 1000) {       // Arbitrary upper limit against badly formed CS.
                     final short key;
                     final Object[] args;
                     if (dimension <= 0) {
@@ -739,7 +742,7 @@ final class GeodeticObjectParser extends
             } while (axis != null);
             if (!isWKT1 || !ignoreAxes) {
                 axes = list.toArray(new CoordinateSystemAxis[list.size()]);
-                Arrays.sort(axes, this);  // Take ORDER[n] elements in account.
+                Arrays.sort(axes, this);                    // Take ORDER[n] elements in account.
             }
         }
         /*
@@ -751,13 +754,13 @@ final class GeodeticObjectParser extends
             if (type == null) {
                 throw parent.missingComponent(WKTKeywords.Axis);
             }
-            String nx = null, x = null;             // Easting or Longitude axis name and abbreviation.
-            String ny = null, y = null;             // Northing or latitude axis name and abbreviation.
-            String nz = null, z = null;             // Depth, height or time axis name and abbreviation.
+            String nx = null, x = null;                     // Easting or Longitude axis name and abbreviation.
+            String ny = null, y = null;                     // Northing or latitude axis name and abbreviation.
+            String nz = null, z = null;                     // Depth, height or time axis name and abbreviation.
             AxisDirection dx = AxisDirection.EAST;
             AxisDirection dy = AxisDirection.NORTH;
-            AxisDirection direction = null;         // Depth, height or time axis direction.
-            Unit<?> unit = defaultUnit;             // Depth, height or time axis unit.
+            AxisDirection direction = null;                 // Depth, height or time axis direction.
+            Unit<?> unit = defaultUnit;                     // Depth, height or time axis unit.
             switch (type) {
                 /*
                  * Cartesian — we can create axes only for geodetic datum, in which case the axes are for
@@ -849,6 +852,18 @@ final class GeodeticObjectParser extends
                     break;
                 }
                 /*
+                 * Parametric — axis name and abbreviation not yet specified by ISO 19111_2.
+                 */
+                case WKTKeywords.parametric: {
+                    if (defaultUnit == null) {
+                        throw parent.missingComponent(WKTKeywords.ParametricUnit);
+                    }
+                    direction = AxisDirection.OTHER;
+                    nz = "Parametric";
+                    z = "p";
+                    break;
+                }
+                /*
                  * Unknown CS type — we can not guess which axes to create.
                  */
                 default: {
@@ -893,7 +908,7 @@ final class GeodeticObjectParser extends
                     case 2: return csFactory.createEllipsoidalCS(csProperties, axes[0], axes[1]);
                     case 3: return csFactory.createEllipsoidalCS(csProperties, axes[0], axes[1], axes[2]);
                 }
-                dimension = (axes.length < 2) ? 2 : 3;  // For error message.
+                dimension = (axes.length < 2) ? 2 : 3;                      // For error message.
                 break;
             }
             case WKTKeywords.Cartesian: {
@@ -901,7 +916,7 @@ final class GeodeticObjectParser extends
                     case 2: return csFactory.createCartesianCS(csProperties, axes[0], axes[1]);
                     case 3: return csFactory.createCartesianCS(csProperties, axes[0], axes[1], axes[2]);
                 }
-                dimension = (axes.length < 2) ? 2 : 3;  // For error message.
+                dimension = (axes.length < 2) ? 2 : 3;                      // For error message.
                 break;
             }
             case WKTKeywords.affine: {
@@ -909,7 +924,7 @@ final class GeodeticObjectParser extends
                     case 2: return csFactory.createAffineCS(csProperties, axes[0], axes[1]);
                     case 3: return csFactory.createAffineCS(csProperties, axes[0], axes[1], axes[2]);
                 }
-                dimension = (axes.length < 2) ? 2 : 3;  // For error message.
+                dimension = (axes.length < 2) ? 2 : 3;                      // For error message.
                 break;
             }
             case WKTKeywords.vertical: {
@@ -936,11 +951,12 @@ final class GeodeticObjectParser extends
                 if (axes.length != (dimension = 3)) break;
                 return csFactory.createSphericalCS(csProperties, axes[0], axes[1], axes[2]);
             }
-            case WKTKeywords.parametric: {  // TODO: not yet supported.
-                return referencing.createAbstractCS(csProperties, axes);
+            case WKTKeywords.parametric: {
+                if (axes.length != (dimension = 1)) break;
+                return csFactory.createParametricCS(csProperties, axes[0]);
             }
             default: {
-                warning(parent, null, Errors.formatInternational(Errors.Keys.UnknownType_1, type), null);
+                warning(parent, WKTKeywords.CS, Errors.formatInternational(Errors.Keys.UnknownType_1, type), null);
                 return referencing.createAbstractCS(csProperties, axes);
             }
         }
@@ -1083,9 +1099,9 @@ final class GeodeticObjectParser extends
             if (n2 != null) {
                 return n1 - n2;
             }
-            return -1;  // Axis 1 before Axis 2 since the later has no 'ORDER' element.
+            return -1;                      // Axis 1 before Axis 2 since the later has no 'ORDER' element.
         } else if (n2 != null) {
-            return +1;  // Axis 2 before Axis 1 since the later has no 'ORDER' element.
+            return +1;                      // Axis 2 before Axis 1 since the later has no 'ORDER' element.
         }
         return 0;
     }
@@ -1157,7 +1173,7 @@ final class GeodeticObjectParser extends
         for (int i=0; i<values.length;) {
             values[i] = element.pullDouble(ToWGS84[i]);
             if ((++i % 3) == 0 && element.isEmpty()) {
-                break;  // It is legal to have only 3 or 6 elements.
+                break;                                              // It is legal to have only 3 or 6 elements.
             }
         }
         element.close(ignoredElements);
@@ -1195,7 +1211,7 @@ final class GeodeticObjectParser extends
         }
         final Map<String,?> properties = parseMetadataAndClose(element, name, null);
         try {
-            if (inverseFlattening == 0) {   // OGC convention for a sphere.
+            if (inverseFlattening == 0) {                           // OGC convention for a sphere.
                 return datumFactory.createEllipsoid(properties, semiMajorAxis, semiMajorAxis, unit);
             } else {
                 return datumFactory.createFlattenedSphere(properties, semiMajorAxis, inverseFlattening, unit);
@@ -1439,6 +1455,31 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Parses a {@code "ParametricDatum"} element. This element has the following pattern:
+     *
+     * {@preformat wkt
+     *     ParametricDatum["<name>", Anchor[...] {,<authority>}]
+     * }
+     *
+     * @param  mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  parent The parent element.
+     * @return The {@code "ParametricDatum"} element as a {@link ParametricDatum} object.
+     * @throws ParseException if the {@code "ParametricDatum"} element can not be parsed.
+     */
+    private ParametricDatum parseParametricDatum(final int mode, final Element parent) throws ParseException {
+        final Element element = parent.pullElement(mode, WKTKeywords.ParametricDatum, WKTKeywords.PDatum);
+        if (element == null) {
+            return null;
+        }
+        final String name = element.pullString("name");
+        try {
+            return datumFactory.createParametricDatum(parseAnchorAndClose(element, name));
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception);
+        }
+    }
+
+    /**
      * Parses a {@code "EngineeringDatum"} (WKT 2) element. The syntax is given by
      * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#76">WKT 2 specification §11.2</a>.
      *
@@ -1464,9 +1505,9 @@ final class GeodeticObjectParser extends
         if (element == null) {
             return null;
         }
-        final String name  = element.pullString ("name");
+        final String name = element.pullString("name");
         if (isWKT1) {
-            element.pullInteger("datum");   // Ignored for now.
+            element.pullInteger("datum");                                       // Ignored for now.
         }
         try {
             return datumFactory.createEngineeringDatum(parseAnchorAndClose(element, name));
@@ -1519,14 +1560,14 @@ final class GeodeticObjectParser extends
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
-                isBaseCRS ? new String[] {WKTKeywords.BaseEngCRS}       // WKT 2 in DerivedCRS
-                          : new String[] {WKTKeywords.EngineeringCRS,   // [0]  WKT 2
-                                          WKTKeywords.EngCRS,           // [1]  WKT 2
-                                          WKTKeywords.Local_CS});       // [2]  WKT 1
+                isBaseCRS ? new String[] {WKTKeywords.BaseEngCRS}               // WKT 2 in DerivedCRS
+                          : new String[] {WKTKeywords.EngineeringCRS,           // [0]  WKT 2
+                                          WKTKeywords.EngCRS,                   // [1]  WKT 2
+                                          WKTKeywords.Local_CS});               // [2]  WKT 1
         if (element == null) {
             return null;
         }
-        final boolean isWKT1 = element.getKeywordIndex() == 2;  // Index of "Local_CS" above.
+        final boolean isWKT1 = element.getKeywordIndex() == 2;                  // Index of "Local_CS" above.
         final String  name   = element.pullString("name");
         final Unit<?> unit   = parseUnit(element);
         /*
@@ -1563,7 +1604,7 @@ final class GeodeticObjectParser extends
                 }
             }
         }
-        if (baseCRS == null) {  // The most usual case.
+        if (baseCRS == null) {                                                  // The most usual case.
             datum = parseEngineeringDatum(MANDATORY, element, isWKT1);
         }
         try {
@@ -1639,18 +1680,18 @@ final class GeodeticObjectParser extends
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
-                (csType != null) ? new String[] {WKTKeywords.BaseGeodCRS,    // [0]  WKT 2 in ProjectedCRS or DerivedCRS
-                                                 WKTKeywords.GeogCS}         // [1]  WKT 1 in ProjectedCRS
-                                 : new String[] {WKTKeywords.GeodeticCRS,    // [0]  WKT 2
-                                                 WKTKeywords.GeogCS,         // [1]  WKT 1
-                                                 WKTKeywords.GeodCRS,        // [2]  WKT 2
-                                                 WKTKeywords.GeocCS});       // [3]  WKT 1
+                (csType != null) ? new String[] {WKTKeywords.BaseGeodCRS,       // [0]  WKT 2 in ProjectedCRS or DerivedCRS
+                                                 WKTKeywords.GeogCS}            // [1]  WKT 1 in ProjectedCRS
+                                 : new String[] {WKTKeywords.GeodeticCRS,       // [0]  WKT 2
+                                                 WKTKeywords.GeogCS,            // [1]  WKT 1
+                                                 WKTKeywords.GeodCRS,           // [2]  WKT 2
+                                                 WKTKeywords.GeocCS});          // [3]  WKT 1
         if (element == null) {
             return null;
         }
         final boolean isWKT1;
-        Unit<?>     csUnit;
-        Unit<Angle> angularUnit;
+        Unit<?> csUnit;
+        final Unit<Angle> angularUnit;
         switch (element.getKeywordIndex()) {
             default: {
                 /*
@@ -1683,7 +1724,7 @@ final class GeodeticObjectParser extends
                          * We recognize those cases by a non-null 'csType' given in argument to this method.
                          */
                         if (WKTKeywords.ellipsoidal.equals(csType)) {
-                            csUnit = NonSI.DEGREE_ANGLE;   // For BaseGeodCRS in ProjectedCRS.
+                            csUnit = NonSI.DEGREE_ANGLE;                        // For BaseGeodCRS in ProjectedCRS.
                         }
                     }
                 }
@@ -1747,7 +1788,7 @@ final class GeodeticObjectParser extends
                 return crsFactory.createDerivedCRS(properties, baseCRS, fromBase, cs);
             }
             /*
-             * The specifiation in §8.2.2 (ii) said:
+             * The specification in §8.2.2 (ii) said:
              *
              *     "(snip) the prime meridian’s <irm longitude> value shall be given in the
              *     same angular units as those for the horizontal axes of the geographic CRS."
@@ -1757,18 +1798,22 @@ final class GeodeticObjectParser extends
              * So we re-fetch the angular unit. Normally, we will get the same value (unless
              * the previous value was null).
              */
-            angularUnit = AxisDirections.getAngularUnit(cs, angularUnit);
-            final PrimeMeridian meridian = parsePrimeMeridian(OPTIONAL, element, isWKT1, angularUnit);
+            final Unit<Angle> longitudeUnit = AxisDirections.getAngularUnit(cs, angularUnit);
+            if (angularUnit != null && !angularUnit.equals(longitudeUnit)) {
+                warning(element, WKTKeywords.AngleUnit, Errors.formatInternational(
+                        Errors.Keys.InconsistentUnitsForCS_1, angularUnit), null);
+            }
+            final PrimeMeridian meridian = parsePrimeMeridian(OPTIONAL, element, isWKT1, longitudeUnit);
             final GeodeticDatum datum = parseDatum(MANDATORY, element, meridian);
             final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
             if (cs instanceof EllipsoidalCS) {  // By far the most frequent case.
                 return crsFactory.createGeographicCRS(properties, datum, (EllipsoidalCS) cs);
             }
-            if (cs instanceof CartesianCS) {    // The second most frequent case.
+            if (cs instanceof CartesianCS) {                                    // The second most frequent case.
                 return crsFactory.createGeocentricCRS(properties, datum,
                         referencing.upgradeGeocentricCS((CartesianCS) cs));
             }
-            if (cs instanceof SphericalCS) {    // Not very common case.
+            if (cs instanceof SphericalCS) {                                    // Not very common case.
                 return crsFactory.createGeocentricCRS(properties, datum, (SphericalCS) cs);
             }
         } catch (FactoryException exception) {
@@ -1793,18 +1838,19 @@ final class GeodeticObjectParser extends
      * @return The {@code "VerticalCRS"} element as a {@link VerticalCRS} object.
      * @throws ParseException if the {@code "VerticalCRS"} element can not be parsed.
      */
+    @SuppressWarnings("null")
     private SingleCRS parseVerticalCRS(final int mode, final Element parent, final boolean isBaseCRS)
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
-                isBaseCRS ? new String[] {WKTKeywords.BaseVertCRS}    // WKT 2 in DerivedCRS
-                          : new String[] {WKTKeywords.VerticalCRS,    // [0]  WKT 2
-                                          WKTKeywords.VertCRS,        // [1]  WKT 2
-                                          WKTKeywords.Vert_CS});      // [2]  WKT 1
+                isBaseCRS ? new String[] {WKTKeywords.BaseVertCRS}              // WKT 2 in DerivedCRS
+                          : new String[] {WKTKeywords.VerticalCRS,              // [0]  WKT 2
+                                          WKTKeywords.VertCRS,                  // [1]  WKT 2
+                                          WKTKeywords.Vert_CS});                // [2]  WKT 1
         if (element == null) {
             return null;
         }
-        final boolean isWKT1 = element.getKeywordIndex() == 2;  // Index of "Vert_CS" above.
+        final boolean isWKT1 = element.getKeywordIndex() == 2;                  // Index of "Vert_CS" above.
         final String  name   = element.pullString("name");
         final Unit<?> unit   = parseUnit(element);
         /*
@@ -1830,7 +1876,7 @@ final class GeodeticObjectParser extends
                 baseCRS = parseVerticalCRS(MANDATORY, element, true);
             }
         }
-        if (baseCRS == null) {                                                              // The most usual case.
+        if (baseCRS == null) {                                                  // The most usual case.
             datum = parseVerticalDatum(MANDATORY, element, isWKT1);
         }
         final CoordinateSystem cs;
@@ -1909,7 +1955,7 @@ final class GeodeticObjectParser extends
                 baseCRS = parseTimeCRS(MANDATORY, element, true);
             }
         }
-        if (baseCRS == null) {  // The most usual case.
+        if (baseCRS == null) {                                                  // The most usual case.
             datum = parseTimeDatum(MANDATORY, element);
         }
         final CoordinateSystem cs;
@@ -1929,6 +1975,66 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Parses {@code "ParametricCRS"} element.
+     *
+     * @param  mode      {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  parent    The parent element.
+     * @param  isBaseCRS {@code true} if parsing the CRS inside a {@code DerivedCRS}.
+     * @return The {@code "ParametricCRS"} object.
+     * @throws ParseException if the {@code "ParametricCRS"} element can not be parsed.
+     */
+    private SingleCRS parseParametricCRS(final int mode, final Element parent, final boolean isBaseCRS)
+            throws ParseException
+    {
+        final Element element = parent.pullElement(mode, isBaseCRS ? WKTKeywords.BaseParamCRS : WKTKeywords.ParametricCRS);
+        if (element == null) {
+            return null;
+        }
+        final String  name = element.pullString("name");
+        final Unit<?> unit = parseUnit(element);
+        /*
+         * A ParametricCRS can be either a "normal" one (with a non-null datum), or a DerivedCRS of kind ParametricCRS.
+         * In the later case, the datum is null and we have instead DerivingConversion element from a BaseParametricCRS.
+         */
+        ParametricDatum datum    = null;
+        SingleCRS       baseCRS  = null;
+        Conversion      fromBase = null;
+        if (!isBaseCRS) {
+            /*
+             * UNIT[…] in DerivedCRS parameters are mandatory according ISO 19162 and the specification does not said
+             * what to do if they are missing.  In this code, we default to the contextual units in the same way than
+             * what we do for ProjectedCRS parameters, in the hope to be consistent.
+             *
+             * An alternative would be to specify null units, in which case MathTransformParser.parseParameters(…)
+             * defaults to the units specified in the parameter descriptor. But this would make the CRS parser more
+             * implementation-dependent, because the parameter descriptors are provided by the MathTransformFactory
+             * instead than inferred from the WKT.
+             */
+            fromBase = parseDerivingConversion(OPTIONAL, element, WKTKeywords.DerivingConversion, unit, null);
+            if (fromBase != null) {
+                baseCRS = parseParametricCRS(MANDATORY, element, true);
+            }
+        }
+        if (baseCRS == null) {                                                  // The most usual case.
+            datum = parseParametricDatum(MANDATORY, element);
+        }
+        final CoordinateSystem cs;
+        try {
+            cs = parseCoordinateSystem(element, WKTKeywords.parametric, 1, false, unit, datum);
+            final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
+            if (cs instanceof ParametricCS) {
+                if (baseCRS != null) {
+                    return crsFactory.createDerivedCRS(properties, baseCRS, fromBase, cs);
+                }
+                return crsFactory.createParametricCRS(properties, datum, (ParametricCS) cs);
+            }
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception);
+        }
+        throw element.illegalCS(cs);
+    }
+
+    /**
      * Parses a {@code "ProjectedCRS"} (WKT 2) element. The syntax is given by
      * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#57">WKT 2 specification §9</a>.
      *
@@ -1949,15 +2055,15 @@ final class GeodeticObjectParser extends
             throws ParseException
     {
         final Element element = parent.pullElement(mode,
-                isBaseCRS ? new String[] {WKTKeywords.BaseProjCRS}    // WKT 2 in DerivedCRS
-                          : new String[] {WKTKeywords.ProjectedCRS,   // [0]  WKT 2
-                                          WKTKeywords.ProjCRS,        // [1]  WKT 2
-                                          WKTKeywords.ProjCS});       // [2]  WKT 1
+                isBaseCRS ? new String[] {WKTKeywords.BaseProjCRS}              // WKT 2 in DerivedCRS
+                          : new String[] {WKTKeywords.ProjectedCRS,             // [0]  WKT 2
+                                          WKTKeywords.ProjCRS,                  // [1]  WKT 2
+                                          WKTKeywords.ProjCS});                 // [2]  WKT 1
 
         if (element == null) {
             return null;
         }
-        final boolean   isWKT1 = element.getKeywordIndex() == 2;  // Index of "ProjCS" above.
+        final boolean   isWKT1 = element.getKeywordIndex() == 2;                // Index of "ProjCS" above.
         final String    name   = element.pullString("name");
         final SingleCRS geoCRS = parseGeodeticCRS(MANDATORY, element, 2, WKTKeywords.ellipsoidal);
         if (!(geoCRS instanceof GeographicCRS)) {

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -348,7 +348,7 @@ public class ImmutableIdentifier extends
             final Map<String,?> properties, final String key, final Object value)
     {
         return new IllegalArgumentException(Errors.getResources(properties)
-                .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
+                .getString(Errors.Keys.IllegalPropertyValueClass_2, key, value.getClass()));
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -197,7 +197,7 @@ public abstract class AbstractEnvelope i
     static CoordinateSystemAxis getAxis(final CoordinateReferenceSystem crs, final int dimension) {
         if (crs != null) {
             final CoordinateSystem cs = crs.getCoordinateSystem();
-            if (cs != null) {   // Paranoiac check (should never be null).
+            if (cs != null) {                                       // Paranoiac check (should never be null).
                 return cs.getAxis(dimension);
             }
         }
@@ -350,7 +350,7 @@ public abstract class AbstractEnvelope i
     @Override
     public double getMinimum(final int dimension) throws IndexOutOfBoundsException {
         double lower = getLower(dimension);
-        if (isNegative(getUpper(dimension) - lower)) { // Special handling for -0.0
+        if (isNegative(getUpper(dimension) - lower)) {              // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(getCoordinateReferenceSystem(), dimension);
             lower = (axis != null) ? axis.getMinimumValue() : Double.NEGATIVE_INFINITY;
         }
@@ -371,7 +371,7 @@ public abstract class AbstractEnvelope i
     @Override
     public double getMaximum(final int dimension) throws IndexOutOfBoundsException {
         double upper = getUpper(dimension);
-        if (isNegative(upper - getLower(dimension))) { // Special handling for -0.0
+        if (isNegative(upper - getLower(dimension))) {              // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(getCoordinateReferenceSystem(), dimension);
             upper = (axis != null) ? axis.getMaximumValue() : Double.POSITIVE_INFINITY;
         }
@@ -406,7 +406,7 @@ public abstract class AbstractEnvelope i
         final double lower = getLower(dimension);
         final double upper = getUpper(dimension);
         double median = 0.5 * (lower + upper);
-        if (isNegative(upper - lower)) { // Special handling for -0.0
+        if (isNegative(upper - lower)) {                            // Special handling for -0.0
             median = fixMedian(getAxis(getCoordinateReferenceSystem(), dimension), median);
         }
         return median;
@@ -453,7 +453,7 @@ public abstract class AbstractEnvelope i
     @Override
     public double getSpan(final int dimension) {
         double span = getUpper(dimension) - getLower(dimension);
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                     // Special handling for -0.0
             span = fixSpan(getAxis(getCoordinateReferenceSystem(), dimension), span);
         }
         return span;
@@ -534,14 +534,14 @@ public abstract class AbstractEnvelope i
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public Envelope[] toSimpleEnvelopes() {
-        long isWrapAround = 0; // A bitmask of the dimensions having a "wrap around" behavior.
+        long isWrapAround = 0;                              // A bitmask of the dimensions having a "wrap around" behavior.
         CoordinateReferenceSystem crs = null;
         final int dimension = getDimension();
         for (int i=0; i!=dimension; i++) {
-            final double span = getUpper(i) - getLower(i); // Do not use getSpan(i).
-            if (!(span > 0)) { // Use '!' for catching NaN.
+            final double span = getUpper(i) - getLower(i);  // Do not use getSpan(i).
+            if (!(span > 0)) {                              // Use '!' for catching NaN.
                 if (!isNegative(span)) {
-                    return EMPTY; // Span is positive zero.
+                    return EMPTY;                           // Span is positive zero.
                 }
                 if (crs == null) {
                     crs = getCoordinateReferenceSystem();
@@ -591,9 +591,9 @@ public abstract class AbstractEnvelope i
              * Assign the minimum and maximum ordinate values in the dimension where a wraparound has been found.
              * The 'for' loop below iterates only over the 'i' values for which the 'isWrapAround' bit is set to 1.
              */
-            int mask = 1; // For identifying whether we need to set the lower or the upper ordinate.
+            int mask = 1;               // For identifying whether we need to set the lower or the upper ordinate.
             @SuppressWarnings("null")
-            final CoordinateSystem cs = crs.getCoordinateSystem(); // Should not be null at this point.
+            final CoordinateSystem cs = crs.getCoordinateSystem();            // Should not be null at this point.
             for (int i; (i = Long.numberOfTrailingZeros(isWrapAround)) != Long.SIZE; isWrapAround &= ~(1L << i)) {
                 final CoordinateSystemAxis axis = cs.getAxis(i);
                 final double min = axis.getMinimumValue();
@@ -637,7 +637,7 @@ public abstract class AbstractEnvelope i
             return true;
         }
         for (int i=0; i<dimension; i++) {
-            if (!(getSpan(i) > 0)) { // Use '!' in order to catch NaN
+            if (!(getSpan(i) > 0)) {                            // Use '!' in order to catch NaN
                 return true;
             }
         }
@@ -710,7 +710,7 @@ public abstract class AbstractEnvelope i
             final boolean c1   = (value >= lower);
             final boolean c2   = (value <= upper);
             if (c1 & c2) {
-                continue; // Point inside the range, check other dimensions.
+                continue;               // Point inside the range, check other dimensions.
             }
             if (c1 | c2) {
                 if (isNegative(upper - lower)) {
@@ -1136,7 +1136,7 @@ public abstract class AbstractEnvelope i
             final DirectPosition lowerCorner = envelope.getLowerCorner();
             final DirectPosition upperCorner = envelope.getUpperCorner();
             boolean isUpper = false;
-            do { // Executed exactly twice.
+            do {                                                        // Executed exactly twice.
                 for (int i=0; i<dimension; i++) {
                     buffer.append(i == 0 && !isUpper ? '(' : ' ');
                     final double ordinate = (isUpper ? upperCorner : lowerCorner).getOrdinate(i);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -109,7 +109,7 @@ class ArrayEnvelope extends AbstractEnve
     public ArrayEnvelope(final DirectPosition lowerCorner, final DirectPosition upperCorner)
             throws MismatchedDimensionException, MismatchedReferenceSystemException
     {
-        crs = getCommonCRS(lowerCorner, upperCorner); // This performs also an argument check.
+        crs = getCommonCRS(lowerCorner, upperCorner);           // This performs also an argument check.
         final int dimension = lowerCorner.getDimension();
         ensureDimensionMatches("crs", dimension, crs);
         ensureSameDimension(dimension, upperCorner.getDimension());
@@ -222,10 +222,10 @@ class ArrayEnvelope extends AbstractEnve
      */
     public ArrayEnvelope(final CharSequence wkt) throws IllegalArgumentException {
         ensureNonNull("wkt", wkt);
-        int levelParenth = 0; // Number of opening parenthesis: (
-        int levelBracket = 0; // Number of opening brackets: [
-        int dimLimit     = 4; // The length of minimum and maximum arrays.
-        int maxDimension = 0; // The number of valid entries in the minimum and maximum arrays.
+        int levelParenth = 0;               // Number of opening parenthesis: (
+        int levelBracket = 0;               // Number of opening brackets: [
+        int dimLimit     = 4;               // The length of minimum and maximum arrays.
+        int maxDimension = 0;               // The number of valid entries in the minimum and maximum arrays.
         final int length = CharSequences.skipTrailingWhitespaces(wkt, 0, wkt.length());
         double[] minimum = new double[dimLimit];
         double[] maximum = new double[dimLimit];
@@ -369,7 +369,7 @@ scanNumber: while ((i += Character.charC
     {
         Object name = IdentifiedObjects.getName(getAxis(crs, dimension), null);
         if (name == null) {
-            name = dimension; // Paranoiac fallback (name should never be null).
+            name = dimension;       // Paranoiac fallback (name should never be null).
         }
         return Errors.format(Errors.Keys.IllegalOrdinateRange_3, lower, upper, name);
     }
@@ -414,7 +414,7 @@ scanNumber: while ((i += Character.charC
      *
      * @return The dimensionality of this envelope.
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public int getDimension() {
         return ordinates.length >>> 1;
     }
@@ -435,7 +435,7 @@ scanNumber: while ((i += Character.charC
     /**
      * {@inheritDoc}
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public double getLower(final int dimension) throws IndexOutOfBoundsException {
         ensureValidIndex(ordinates.length >>> 1, dimension);
         return ordinates[dimension];
@@ -444,7 +444,7 @@ scanNumber: while ((i += Character.charC
     /**
      * {@inheritDoc}
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public double getUpper(final int dimension) throws IndexOutOfBoundsException {
         final int d = ordinates.length >>> 1;
         ensureValidIndex(d, dimension);
@@ -459,7 +459,7 @@ scanNumber: while ((i += Character.charC
         ensureValidIndex(endIndex(), dimension);
         final int i = dimension + beginIndex();
         double lower = ordinates[i];
-        if (isNegative(ordinates[i + (ordinates.length >>> 1)] - lower)) { // Special handling for -0.0
+        if (isNegative(ordinates[i + (ordinates.length >>> 1)] - lower)) {      // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(crs, dimension);
             lower = (axis != null) ? axis.getMinimumValue() : Double.NEGATIVE_INFINITY;
         }
@@ -474,7 +474,7 @@ scanNumber: while ((i += Character.charC
         ensureValidIndex(endIndex(), dimension);
         final int i = dimension + beginIndex();
         double upper = ordinates[i + (ordinates.length >>> 1)];
-        if (isNegative(upper - ordinates[i])) { // Special handling for -0.0
+        if (isNegative(upper - ordinates[i])) {                                 // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(crs, dimension);
             upper = (axis != null) ? axis.getMaximumValue() : Double.POSITIVE_INFINITY;
         }
@@ -491,7 +491,7 @@ scanNumber: while ((i += Character.charC
         final double minimum = ordinates[i];
         final double maximum = ordinates[i + (ordinates.length >>> 1)];
         double median = 0.5 * (minimum + maximum);
-        if (isNegative(maximum - minimum)) { // Special handling for -0.0
+        if (isNegative(maximum - minimum)) {                                    // Special handling for -0.0
             median = fixMedian(getAxis(crs, dimension), median);
         }
         return median;
@@ -505,7 +505,7 @@ scanNumber: while ((i += Character.charC
         ensureValidIndex(endIndex(), dimension);
         final int i = dimension + beginIndex();
         double span = ordinates[i + (ordinates.length >>> 1)] - ordinates[i];
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                                 // Special handling for -0.0
             span = fixSpan(getAxis(crs, dimension), span);
         }
         return span;
@@ -524,7 +524,7 @@ scanNumber: while ((i += Character.charC
         final int d = ordinates.length >>> 1;
         for (int i=beginIndex; i<endIndex; i++) {
             final double span = ordinates[i+d] - ordinates[i];
-            if (!(span > 0)) { // Use '!' in order to catch NaN
+            if (!(span > 0)) {                                                  // Use '!' in order to catch NaN
                 if (!(isNegative(span) && isWrapAround(crs, i - beginIndex))) {
                     return true;
                 }
@@ -537,7 +537,7 @@ scanNumber: while ((i += Character.charC
     /**
      * {@inheritDoc}
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public boolean isAllNaN() {
         for (int i=0; i<ordinates.length; i++) {
             if (!Double.isNaN(ordinates[i])) {
@@ -551,7 +551,7 @@ scanNumber: while ((i += Character.charC
     /**
      * {@inheritDoc}
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public int hashCode() {
         int code = Arrays.hashCode(ordinates);
         if (crs != null) {
@@ -572,7 +572,7 @@ scanNumber: while ((i += Character.charC
     /**
      * {@inheritDoc}
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                       // Must also be overridden in SubEnvelope
     public boolean equals(final Object object) {
         if (object != null && object.getClass() == getClass()) {
             final ArrayEnvelope that = (ArrayEnvelope) object;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -233,7 +233,7 @@ public class Envelope2D extends Rectangl
     public Envelope2D(final CoordinateReferenceSystem crs, final Rectangle2D rect)
             throws MismatchedDimensionException
     {
-        super(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); // Really 'super', not 'this'.
+        super(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());     // Really 'super', not 'this'.
         ensureDimensionMatches("crs", DIMENSION, crs);
         this.crs = crs;
     }
@@ -256,7 +256,7 @@ public class Envelope2D extends Rectangl
     public Envelope2D(final CoordinateReferenceSystem crs, final double x, final double y,
             final double width, final double height) throws MismatchedDimensionException
     {
-        super(x, y, width, height); // Really 'super', not 'this'.
+        super(x, y, width, height);                             // Really 'super', not 'this'.
         ensureDimensionMatches("crs", DIMENSION, crs);
         this.crs = crs;
     }
@@ -364,7 +364,7 @@ public class Envelope2D extends Rectangl
             case 1:  value=y; span=height; break;
             default: throw indexOutOfBounds(dimension);
         }
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                         // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(crs, dimension);
             return (axis != null) ? axis.getMinimumValue() : NEGATIVE_INFINITY;
         }
@@ -388,7 +388,7 @@ public class Envelope2D extends Rectangl
             case 1:  value=y; span=height; break;
             default: throw indexOutOfBounds(dimension);
         }
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                         // Special handling for -0.0
             final CoordinateSystemAxis axis = getAxis(crs, dimension);
             return (axis != null) ? axis.getMaximumValue() : POSITIVE_INFINITY;
         }
@@ -413,7 +413,7 @@ public class Envelope2D extends Rectangl
             default: throw indexOutOfBounds(dimension);
         }
         value += 0.5*span;
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                         // Special handling for -0.0
             value = fixMedian(getAxis(crs, dimension), value);
         }
         return value;
@@ -435,7 +435,7 @@ public class Envelope2D extends Rectangl
             case 1:  span=height; break;
             default: throw indexOutOfBounds(dimension);
         }
-        if (isNegative(span)) { // Special handling for -0.0
+        if (isNegative(span)) {                                         // Special handling for -0.0
             span = fixSpan(getAxis(crs, dimension), span);
         }
         return span;
@@ -570,11 +570,12 @@ public class Envelope2D extends Rectangl
      *
      * @since 0.4
      */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public Rectangle2D.Double[] toRectangles() {
-        int isWrapAround = 0; // A bitmask of the dimensions having a "wrap around" behavior.
+        int isWrapAround = 0;                   // A bitmask of the dimensions having a "wrap around" behavior.
         for (int i=0; i!=DIMENSION; i++) {
             final double span = (i == 0) ? width : height;
-            if (!(span > 0)) { // Use '!' for catching NaN.
+            if (!(span > 0)) {                                                      // Use '!' for catching NaN.
                 if (!isNegative(span) || !isWrapAround(crs, i)) {
                     return EMPTY;
                 }
@@ -614,7 +615,7 @@ public class Envelope2D extends Rectangl
              */
             final CoordinateSystemAxis axis = getAxis(crs, 1);
             final Rectangle2D.Double start = rect[0];
-            final Rectangle2D.Double next  = rect[isWrapAround - 1]; // == 1 if y is the only wraparound axis, or 2 otherwise.
+            final Rectangle2D.Double next  = rect[isWrapAround - 1];    // == 1 if y is the only wraparound axis, or 2 otherwise.
             start.height = axis.getMaximumValue() - y;
             next.y       = axis.getMinimumValue();
             next.height += y - next.y;
@@ -839,14 +840,14 @@ public class Envelope2D extends Rectangl
             /*
              * See GeneralEnvelope.intersect(Envelope) for an explanation of the algorithm applied below.
              */
-            if (isSameSign(span0, span1)) { // Always 'false' if any value is NaN.
+            if (isSameSign(span0, span1)) {                 // Always 'false' if any value is NaN.
                 if ((min1 > max0 || max1 < min0) && !isNegativeUnsafe(span0)) {
-                    continue; // No intersection: leave ordinate values to NaN
+                    continue;                               // No intersection: leave ordinate values to NaN
                 }
             } else if (isNaN(span0) || isNaN(span1)) {
-                continue; // Leave ordinate values to NaN
+                continue;                                   // Leave ordinate values to NaN
             } else {
-                int intersect = 0; // A bitmask of intersections (two bits).
+                int intersect = 0;                          // A bitmask of intersections (two bits).
                 if (isNegativeUnsafe(span0)) {
                     if (min1 <= max0) {min = min1; intersect  = 1;}
                     if (max1 >= min0) {max = max1; intersect |= 2;}
@@ -863,7 +864,7 @@ public class Envelope2D extends Rectangl
                         min = min1;
                         max = max1;
                     } else {
-                        continue; // Leave ordinate values to NaN
+                        continue;                           // Leave ordinate values to NaN
                     }
                 }
             }
@@ -931,7 +932,7 @@ public class Envelope2D extends Rectangl
             final boolean sp1 = isNegative(span1);
             if (sp0 == sp1) {
                 if (sp0 && !isNegativeUnsafe(max - min)) {
-                    continue; // Leave ordinates to NaN.
+                    continue;                                   // Leave ordinates to NaN.
                 }
             } else if (sp0) {
                 if (max1 <= max0 || min1 >= min0) {
@@ -941,7 +942,7 @@ public class Envelope2D extends Rectangl
                     final double left  = min1 - max0;
                     final double right = min0 - max1;
                     if (!(left > 0 || right > 0)) {
-                        continue; // Leave ordinates to NaN.
+                        continue;                               // Leave ordinates to NaN.
                     }
                     if (left > right) {min = min1; max = max0;}
                     if (right > left) {min = min0; max = max1;}
@@ -954,7 +955,7 @@ public class Envelope2D extends Rectangl
                     final double left  = min0 - max1;
                     final double right = min1 - max0;
                     if (!(left > 0 || right > 0)) {
-                        continue; // Leave ordinates to NaN.
+                        continue;                               // Leave ordinates to NaN.
                     }
                     if (left > right) {min = min0; max = max1;}
                     if (right > left) {min = min1; max = max0;}
@@ -1001,7 +1002,7 @@ public class Envelope2D extends Rectangl
     @Override
     public void add(final double px, final double py) {
         double off = px - x;
-        if (!isNegative(width)) { // Standard case, or NaN.
+        if (!isNegative(width)) {                           // Standard case, or NaN.
             if (off < 0) {x=px; width -= off;}
             if (off > width)   {width  = off;}
         } else if (off < 0) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -29,7 +29,6 @@ import org.opengis.referencing.cs.Coordi
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
@@ -42,9 +41,9 @@ import org.apache.sis.util.logging.Loggi
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
+import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.DirectPositionView;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.system.Loggers;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -102,17 +101,6 @@ public final class Envelopes extends Sta
     }
 
     /**
-     * Returns the coordinate operation factory to be used for transforming the envelope.
-     */
-    private static CoordinateOperationFactory getFactory() throws TransformException {
-        final CoordinateOperationFactory factory = DefaultFactories.forClass(CoordinateOperationFactory.class);
-        if (factory != null) {
-            return factory;
-        }
-        throw new TransformException(Errors.format(Errors.Keys.MissingRequiredModule_1, "geotk-referencing")); // This is temporary.
-    }
-
-    /**
      * Returns {@code true} if the given axis is of kind "Wrap Around".
      */
     private static boolean isWrapAround(final CoordinateSystemAxis axis) {
@@ -184,7 +172,7 @@ public final class Envelopes extends Sta
                 } else {
                     final CoordinateOperation operation;
                     try {
-                        operation = getFactory().createOperation(sourceCRS, targetCRS);
+                        operation = CoordinateOperations.factory().createOperation(sourceCRS, targetCRS);
                     } catch (FactoryException exception) {
                         throw new TransformException(Errors.format(Errors.Keys.CanNotTransformEnvelope), exception);
                     }
@@ -304,11 +292,11 @@ public final class Envelopes extends Sta
                         sourcePt, ordinates, offset, isDerivativeSupported);
             } catch (TransformException e) {
                 if (!isDerivativeSupported) {
-                    throw e; // Derivative were already disabled, so something went wrong.
+                    throw e;                    // Derivative were already disabled, so something went wrong.
                 }
                 isDerivativeSupported = false;
                 transform.transform(sourcePt, 0, ordinates, offset, 1);
-                recoverableException(e); // Log only if the above call was successful.
+                recoverableException(e);        // Log only if the above call was successful.
             }
             /*
              * The transformed point has been saved for future reuse after the enclosing
@@ -336,10 +324,10 @@ public final class Envelopes extends Sta
             int indexBase3 = ++pointIndex;
             for (int dim=sourceDim; --dim>=0; indexBase3 /= 3) {
                 switch (indexBase3 % 3) {
-                    case 0:  sourcePt[dim] = envelope.getMinimum(dim); break; // Continue the loop.
+                    case 0:  sourcePt[dim] = envelope.getMinimum(dim); break;   // Continue the loop.
                     case 1:  sourcePt[dim] = envelope.getMaximum(dim); continue transformPoint;
                     case 2:  sourcePt[dim] = envelope.getMedian (dim); continue transformPoint;
-                    default: throw new AssertionError(indexBase3); // Should never happen
+                    default: throw new AssertionError(indexBase3);     // Should never happen
                 }
             }
             break;
@@ -469,7 +457,7 @@ public final class Envelopes extends Sta
                  */
                 final MathTransform mt;
                 try {
-                    mt = getFactory().createOperation(crs, sourceCRS).getMathTransform();
+                    mt = CoordinateOperations.factory().createOperation(crs, sourceCRS).getMathTransform();
                 } catch (FactoryException e) {
                     throw new TransformException(Errors.format(Errors.Keys.CanNotTransformEnvelope), e);
                 }
@@ -703,9 +691,9 @@ public final class Envelopes extends Sta
                          * or skip c={2,3}.
                          */
                         double value = max;
-                        if ((c & 1) == 0) { // 'true' if we are testing "wrapAroundMin".
+                        if ((c & 1) == 0) {         // 'true' if we are testing "wrapAroundMin".
                             if (((c == 0 ? includedMinValue : includedMaxValue) & bm) == 0) {
-                                c++; // Skip also the case for "wrapAroundMax".
+                                c++;                // Skip also the case for "wrapAroundMax".
                                 continue;
                             }
                             targetPt.setOrdinate(axisIndex, (c == 0) ? axis.getMinimumValue() : axis.getMaximumValue());

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -127,7 +127,7 @@ public class GeneralDirectPosition exten
      * @param point The position to copy.
      */
     public GeneralDirectPosition(final DirectPosition point) {
-        ordinates = point.getCoordinate(); // Should already be cloned.
+        ordinates = point.getCoordinate();                              // Should already be cloned.
         crs = point.getCoordinateReferenceSystem();
         ensureDimensionMatches("crs", ordinates.length, crs);
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -313,7 +313,7 @@ public class GeneralEnvelope extends Arr
                 }
             }
         }
-        this.crs = crs; // Set only on success.
+        this.crs = crs;                                             // Set only on success.
     }
 
     /**
@@ -326,7 +326,7 @@ public class GeneralEnvelope extends Arr
      * @throws IllegalArgumentException If {@code lower > upper} and the axis range meaning at the given dimension
      *         is not "wraparound". See <cite>Envelope validation</cite> in class javadoc for more details.
      */
-    @Override // Must also be overridden in SubEnvelope
+    @Override                                                           // Must also be overridden in SubEnvelope
     public void setRange(final int dimension, final double lower, final double upper)
             throws IndexOutOfBoundsException
     {
@@ -433,8 +433,7 @@ public class GeneralEnvelope extends Arr
      *
      * @see #isAllNaN()
      */
-    // Must be overridden in SubEnvelope
-    public void setToNaN() {
+    public void setToNaN() {                   // Must be overridden in SubEnvelope
         Arrays.fill(ordinates, Double.NaN);
         assert isAllNaN() : this;
     }
@@ -523,7 +522,7 @@ public class GeneralEnvelope extends Arr
             final double value = position.getOrdinate(i);
             final double min = ordinates[iLower];
             final double max = ordinates[iUpper];
-            if (!isNegative(max - min)) { // Standard case, or NaN.
+            if (!isNegative(max - min)) {                       // Standard case, or NaN.
                 if (value < min) ordinates[iLower] = value;
                 if (value > max) ordinates[iUpper] = value;
             } else {
@@ -622,7 +621,7 @@ public class GeneralEnvelope extends Arr
                 if (min1 < min0) ordinates[iLower] = min1;
                 if (max1 > max0) ordinates[iUpper] = max1;
                 if (!sp0 || isNegativeUnsafe(ordinates[iUpper] - ordinates[iLower])) {
-                    continue; // We are done, go to the next dimension.
+                    continue;               // We are done, go to the next dimension.
                 }
                 // If we were spanning the anti-meridian before the union but
                 // are not anymore after the union, we actually merged to two
@@ -638,8 +637,8 @@ public class GeneralEnvelope extends Arr
                  *     └────┘  │  │
                  *   ──────────┘  └─────
                  */
-                if (max1 <= max0) continue;  // This is the case of above picture.
-                if (min1 >= min0) continue;  // Like above picture, but on the right side.
+                if (max1 <= max0) continue;             // This is the case of above picture.
+                if (min1 >= min0) continue;             // Like above picture, but on the right side.
                 /*
                  * At this point, the given envelope partially overlaps the "exclusion area"
                  * of this envelope or has NaN values. We will move at most one edge of this
@@ -655,8 +654,8 @@ public class GeneralEnvelope extends Arr
                     // The < and > checks below are not completly redundant.
                     // The difference is when a value is NaN.
                     if (left > right) ordinates[iLower] = min1;
-                    if (right > left) ordinates[iUpper] = max1; // This is the case illustrated above.
-                    continue; // We are done, go to the next dimension.
+                    if (right > left) ordinates[iUpper] = max1;     // This is the case illustrated above.
+                    continue;                                       // We are done, go to the next dimension.
                 }
                 // If we reach this point, the given envelope fills completly the "exclusion area"
                 // of this envelope. As a consequence this envelope is now spanning to infinities.
@@ -729,7 +728,7 @@ public class GeneralEnvelope extends Arr
             final double max1  = upper.getOrdinate(i);
             final double span0 = max0 - min0;
             final double span1 = max1 - min1;
-            if (isSameSign(span0, span1)) { // Always 'false' if any value is NaN.
+            if (isSameSign(span0, span1)) {                 // Always 'false' if any value is NaN.
                 /*
                  * First, verify that the two envelopes intersect.
                  *     ┌──────────┐             ┌─────────────┐
@@ -757,7 +756,7 @@ public class GeneralEnvelope extends Arr
                     continue;
                 }
             } else {
-                int intersect = 0; // A bitmask of intersections (two bits).
+                int intersect = 0;                          // A bitmask of intersections (two bits).
                 if (!Double.isNaN(span0) && !Double.isNaN(span1)) {
                     if (isNegativeUnsafe(span0)) {
                         /*

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/SubEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/SubEnvelope.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/SubEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/SubEnvelope.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -207,6 +207,7 @@ final class SubEnvelope extends GeneralE
      * If the user wants a clone, copy only the relevant part of the ordinates array.
      */
     @Override
+    @SuppressWarnings("CloneDoesntCallSuperClone")
     public GeneralEnvelope clone() {
         final int d = ordinates.length >>> 1;
         final int dimension = endIndex - beginIndex;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CC_OperationMethod.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -30,10 +30,9 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.OperationMethod;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.gco.PropertyType;
-import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.referencing.CoordinateOperations;
 import org.apache.sis.internal.referencing.provider.MapProjection;
 import org.apache.sis.parameter.DefaultParameterValue;
 import org.apache.sis.parameter.DefaultParameterValueGroup;
@@ -50,7 +49,7 @@ import org.apache.sis.util.ArraysExt;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public final class CC_OperationMethod extends PropertyType<CC_OperationMethod, OperationMethod> {
@@ -180,13 +179,13 @@ public final class CC_OperationMethod ex
      * @return A parameter group containing at least the given descriptors, or equivalent descriptors.
      */
     public static ParameterDescriptorGroup group(final Identifier name, final GeneralParameterDescriptor[] descriptors) {
-        final CoordinateOperationFactory factory = DefaultFactories.forClass(CoordinateOperationFactory.class);
-        OperationMethod method = null;
-        if (factory != null) try {
-            method = factory.getOperationMethod(name.getCode());
+        OperationMethod method;
+        try {
+            method = CoordinateOperations.factory().getOperationMethod(name.getCode());
         } catch (FactoryException e) {
             // Use DefaultOperationMethod as the source class because it is the first public class in callers.
             Context.warningOccured(Context.current(), DefaultOperationMethod.class, "setDescriptors", e, true);
+            method = null;
         }
         final Map<String,?> properties = Collections.singletonMap(ParameterDescriptorGroup.NAME_KEY, name);
         if (method != null) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -143,7 +143,7 @@ public class GeodeticObjectBuilder exten
      */
     private CoordinateOperationFactory getCoordinateOperationFactory() {
         if (copFactory == null) {
-            copFactory = DefaultFactories.forBuildin(CoordinateOperationFactory.class);
+            copFactory = CoordinateOperations.factory();
         }
         return copFactory;
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Legacy.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -18,9 +18,9 @@ package org.apache.sis.internal.referenc
 
 import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CartesianCS;
-import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.cs.AxisFilter;
 import org.apache.sis.referencing.cs.CoordinateSystems;
@@ -40,10 +40,10 @@ import static org.opengis.referencing.Id
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
-public final class Legacy implements AxisFilter {
+public final class Legacy {
     /**
      * A three-dimensional Cartesian CS with the legacy set of geocentric axes.
      * OGC 01-009 defines the default geocentric axes as:
@@ -62,6 +62,12 @@ public final class Legacy implements Axi
             new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Z"), "Z", AxisDirection.NORTH, SI.METRE));
 
     /**
+     * Do not allow instantiation of this class.
+     */
+    private Legacy() {
+    }
+
+    /**
      * The standard three-dimensional Cartesian CS as defined by ISO 19111.
      *
      * @param  unit The linear unit of the desired coordinate system, or {@code null} for metres.
@@ -108,71 +114,8 @@ public final class Legacy implements Axi
      */
     public static CartesianCS replaceUnit(CartesianCS cs, final Unit<?> unit) {
         if (unit != null && !unit.equals(SI.METRE)) {
-            cs = (CartesianCS) CoordinateSystems.replaceAxes(cs, new Legacy(unit));
+            cs = (CartesianCS) CoordinateSystems.replaceLinearUnit(cs, unit.asType(Length.class));
         }
         return cs;
     }
-
-
-
-
-    // -----------------------------------------------------------------
-    //         AxisFilter implementation for internal usage only
-    // -----------------------------------------------------------------
-
-    /**
-     * The value to be returned by {@link #getUnitReplacement(CoordinateSystemAxis, Unit)},
-     * or {@code null} if no replacement should be done.
-     */
-    private final Unit<?> replacement;
-
-    /**
-     * For internal usage by {@link #replaceUnit(CartesianCS, Unit)} only.
-     */
-    private Legacy(final Unit<?> unit) {
-        replacement = unit;
-    }
-
-    @Override
-    @Deprecated
-    public Unit<?> getUnitReplacement(Unit<?> unit) {
-        return getUnitReplacement(null, unit);
-    }
-
-    /**
-     * For internal usage by {@link #replaceUnit(CartesianCS, Unit)} only.
-     *
-     * @param  axis ignored.
-     * @param  unit ignored.
-     * @return The unit of the new coordinate system.
-     */
-    @Override
-    public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, final Unit<?> unit) {
-        return replacement;
-    }
-
-    /**
-     * Returns the given axis unchanged.
-     */
-    @Override
-    public boolean accept(final CoordinateSystemAxis axis) {
-        return true;
-    }
-
-    /**
-     * Returns the given direction unchanged.
-     */
-    @Override
-    @Deprecated
-    public AxisDirection getDirectionReplacement(final AxisDirection direction) {
-        return direction;
-    }
-
-    /**
-     * Returns the given direction unchanged.
-     */
-    @Override
-    public AxisDirection getDirectionReplacement(CoordinateSystemAxis axis, final AxisDirection direction) {
-        return direction;
-    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -67,7 +67,7 @@ public final class PositionalAccuracyCon
      *
      * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy()
      */
-    private static final double UNKNOWN_ACCURACY = 3000;
+    public static final double UNKNOWN_ACCURACY = 3000;
 
     /**
      * Default accuracy of datum shift, if not explicitly provided in the EPSG database.
@@ -131,8 +131,8 @@ public final class PositionalAccuracyCon
      * This method tries each of the following procedures and returns the first successful one:
      *
      * <ul>
-     *   <li>If a {@link QuantitativeResult} is found with a linear unit, then this accuracy estimate
-     *       is converted to {@linkplain SI#METRE metres} and returned.</li>
+     *   <li>If at least one {@link QuantitativeResult} is found with a linear unit, then the largest
+     *       accuracy estimate is converted to {@linkplain SI#METRE metres} and returned.</li>
      *   <li>Otherwise, if the operation is a {@link Conversion}, then returns 0 since a conversion
      *       is by definition accurate up to rounding errors.</li>
      *   <li>Otherwise, if the operation is a {@link Transformation}, then checks if the datum shift
@@ -152,9 +152,10 @@ public final class PositionalAccuracyCon
      * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy()
      */
     public static double getLinearAccuracy(final CoordinateOperation operation) {
+        double accuracy = Double.NaN;
         final Collection<PositionalAccuracy> accuracies = operation.getCoordinateOperationAccuracy();
-        for (final PositionalAccuracy accuracy : accuracies) {
-            for (final Result result : accuracy.getResults()) {
+        for (final PositionalAccuracy metadata : accuracies) {
+            for (final Result result : metadata.getResults()) {
                 if (result instanceof QuantitativeResult) {
                     final QuantitativeResult quantity = (QuantitativeResult) result;
                     final Collection<? extends Record> records = quantity.getValues();
@@ -167,7 +168,9 @@ public final class PositionalAccuracyCon
                                     if (value instanceof Number) {
                                         double v = ((Number) value).doubleValue();
                                         v = unitOfLength.getConverterTo(SI.METRE).convert(v);
-                                        return v;
+                                        if (v >= 0 && !(v <= accuracy)) {       // '!' is for replacing the NaN value.
+                                            accuracy = v;
+                                        }
                                     }
                                 }
                             }
@@ -176,40 +179,41 @@ public final class PositionalAccuracyCon
                 }
             }
         }
-        /*
-         * No quantitative (linear) accuracy were found. If the coordinate operation is actually
-         * a conversion, the accuracy is up to rounding error (i.e. conceptually 0) by definition.
-         */
-        if (operation instanceof Conversion) {
-            return 0;
-        }
-        /*
-         * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters
-         * were available for the datum shift. This is SIS-specific. See field javadoc for a rational
-         * about the return values chosen.
-         */
-        if (operation instanceof Transformation) {
-            if (accuracies.contains(DATUM_SHIFT_APPLIED)) {
-                return DATUM_SHIFT_ACCURACY;
+        if (Double.isNaN(accuracy)) {
+            /*
+             * No quantitative (linear) accuracy were found. If the coordinate operation is actually
+             * a conversion, the accuracy is up to rounding error (i.e. conceptually 0) by definition.
+             */
+            if (operation instanceof Conversion) {
+                return 0;
             }
-            if (accuracies.contains(DATUM_SHIFT_OMITTED)) {
-                return UNKNOWN_ACCURACY;
+            /*
+             * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters
+             * were available for the datum shift. This is SIS-specific. See field javadoc for a rational
+             * about the return values chosen.
+             */
+            if (operation instanceof Transformation) {
+                if (accuracies.contains(DATUM_SHIFT_APPLIED)) {
+                    return DATUM_SHIFT_ACCURACY;
+                }
+                if (accuracies.contains(DATUM_SHIFT_OMITTED)) {
+                    return UNKNOWN_ACCURACY;
+                }
             }
-        }
-        /*
-         * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy,
-         * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario,
-         * since it could be worst if the transforms are highly non-linear).
-         */
-        double accuracy = Double.NaN;
-        if (operation instanceof ConcatenatedOperation) {
-            for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) {
-                final double candidate = Math.abs(getLinearAccuracy(op));
-                if (!Double.isNaN(candidate)) {
-                    if (Double.isNaN(accuracy)) {
-                        accuracy = candidate;
-                    } else {
-                        accuracy += candidate;
+            /*
+             * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy,
+             * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario,
+             * since it could be worst if the transforms are highly non-linear).
+             */
+            if (operation instanceof ConcatenatedOperation) {
+                for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) {
+                    final double candidate = Math.abs(getLinearAccuracy(op));
+                    if (!Double.isNaN(candidate)) {
+                        if (Double.isNaN(accuracy)) {
+                            accuracy = candidate;
+                        } else {
+                            accuracy += candidate;
+                        }
                     }
                 }
             }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -247,9 +247,16 @@ public final class ReferencingUtilities
     /**
      * Returns the properties of the given object but potentially with a modified name.
      * Current implement truncates the name at the first non-white character which is not
-     * a valid Unicode identifier part.
+     * a valid Unicode identifier part, with the following exception:
+     *
+     * <ul>
+     *   <li>If the character is {@code '('} and the content until the closing {@code ')'} is a valid
+     *       Unicode identifier, then that part is included. The intend is to keep the prime meridian
+     *       name in names like <cite>"NTF (Paris)"</cite>.</li>
+     * </ul>
      *
      * <div class="note"><b>Example:</b><ul>
+     *   <li><cite>"NTF (Paris)"</cite> is left unchanged.</li>
      *   <li><cite>"WGS 84 (3D)"</cite> is truncated as <cite>"WGS 84"</cite>.</li>
      *   <li><cite>"Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: degree"</cite>
      *       is truncated as <cite>"Ellipsoidal 2D CS"</cite>.</li>
@@ -272,6 +279,15 @@ public final class ReferencingUtilities
                 for (int i=0; i < name.length();) {
                     final int c = name.codePointAt(i);
                     if (!Character.isUnicodeIdentifierPart(c) && !Character.isSpaceChar(c)) {
+                        if (c == '(') {
+                            final int endAt = name.indexOf(')', i);
+                            if (endAt >= 0) {
+                                final String extra = name.substring(i+1, endAt);
+                                if (CharSequences.isUnicodeIdentifier(extra)) {
+                                    i += extra.length() + 2;
+                                }
+                            }
+                        }
                         name = CharSequences.trimWhitespaces(name, 0, i).toString();
                         if (!name.isEmpty()) {
                             final Map<String,Object> copy = new HashMap<>(properties);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1740146&r1=1740145&r2=1740146&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Wed Apr 20 13:49:33 2016
@@ -17,8 +17,10 @@
 package org.apache.sis.internal.referencing;
 
 import java.util.Map;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Locale;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
@@ -34,6 +36,9 @@ import org.opengis.referencing.crs.Tempo
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.cs.CSFactory;
+import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
@@ -54,7 +59,6 @@ import org.opengis.metadata.extent.Geogr
 import org.opengis.metadata.extent.VerticalExtent;
 import org.opengis.geometry.Envelope;
 
-import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
@@ -88,6 +92,9 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.Utilities;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+
 
 /**
  * Implements the referencing services needed by the {@code "sis-metadata"} module.
@@ -151,7 +158,7 @@ public final class ServicesForMetadata e
                 !Utilities.equalsIgnoreMetadata(cs2.getAxis(1), cs1.getAxis(1)))
             {
                 final CoordinateOperation operation;
-                final CoordinateOperationFactory factory = DefaultFactories.forBuildin(CoordinateOperationFactory.class);
+                final CoordinateOperationFactory factory = CoordinateOperations.factory();
                 try {
                     operation = factory.createOperation(crs, normalizedCRS);
                 } catch (FactoryException e) {
@@ -611,7 +618,7 @@ public final class ServicesForMetadata e
         if (factory instanceof DefaultCoordinateOperationFactory) {
             df = (DefaultCoordinateOperationFactory) factory;
         } else {
-            df = DefaultFactories.forBuildin(CoordinateOperationFactory.class, DefaultCoordinateOperationFactory.class);
+            df = CoordinateOperations.factory();
         }
         return df.createSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, null);
     }
@@ -623,17 +630,30 @@ public final class ServicesForMetadata e
      *
      * @param  properties The default properties.
      * @param  mtFactory  The math transform factory to use.
+     * @param  crsFactory The factory to use if the operation factory needs to create CRS for intermediate steps.
+     * @param  csFactory  The factory to use if the operation factory needs to create CS for intermediate steps.
      * @return The coordinate operation factory to use.
      *
-     * @since 0.6
+     * @since 0.7
      */
     @Override
-    public CoordinateOperationFactory getCoordinateOperationFactory(Map<String,?> properties, MathTransformFactory mtFactory) {
-        if (Containers.isNullOrEmpty(properties) && DefaultFactories.isDefaultInstance(MathTransformFactory.class, mtFactory)) {
-            return DefaultFactories.forBuildin(CoordinateOperationFactory.class);
-        } else {
-            return new DefaultCoordinateOperationFactory(properties, mtFactory);
+    public CoordinateOperationFactory getCoordinateOperationFactory(Map<String,?> properties,
+            final MathTransformFactory mtFactory, final CRSFactory crsFactory, final CSFactory csFactory)
+    {
+        if (Containers.isNullOrEmpty(properties)) {
+            if (DefaultFactories.isDefaultInstance(MathTransformFactory.class, mtFactory) &&
+                DefaultFactories.isDefaultInstance(CRSFactory.class, crsFactory) &&
+                DefaultFactories.isDefaultInstance(CSFactory.class, csFactory))
+            {
+                return CoordinateOperations.factory();
+            }
+            properties = Collections.emptyMap();
         }
+        final HashMap<String,Object> p = new HashMap<>(properties);
+        JDK8.putIfAbsent(p, CRS_FACTORY, crsFactory);
+        JDK8.putIfAbsent(p, CS_FACTORY,  csFactory);
+        properties = p;
+        return new DefaultCoordinateOperationFactory(properties, mtFactory);
     }
 
     /**




Mime
View raw message