sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1686282 [3/4] - in /sis/trunk: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/test/java/org/apache/sis/feature/ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/ja...
Date Thu, 18 Jun 2015 17:38:17 GMT
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -24,6 +24,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.util.InternationalString;
+import org.apache.sis.internal.util.Citations;
 
 import static org.opengis.annotation.Obligation.OPTIONAL;
 import static org.opengis.annotation.Specification.ISO_19115;
@@ -81,7 +82,7 @@ import static org.opengis.annotation.Spe
  * @author  Touraïvane (IRD)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see ImmutableIdentifier
@@ -144,15 +145,32 @@ public class DefaultIdentifier extends I
 
     /**
      * Creates an identifier initialized to the given authority and code.
+     * This constructor automatically initializes the {@linkplain #getCodeSpace() code space} to a value inferred
+     * from the given {@code authority}, if a suitable value can be found. This constructor proceeds by searching
+     * for the first suitable property in the following list:
+     *
+     * <ol>
+     *   <li>The value of {@link org.apache.sis.xml.IdentifierSpace#getName()}.</li>
+     *   <li>A {@linkplain org.apache.sis.metadata.iso.citation.DefaultCitation#getIdentifiers() citation identifier}
+     *       which is a valid
+     *       {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence) unicode identifier}.</li>
+     *   <li>Only if the citation has no identifier, a citation title or
+     *       {@linkplain org.apache.sis.metadata.iso.citation.DefaultCitation#getAlternateTitles() alternate title}
+     *       which is a valid
+     *       {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence) unicode identifier}.</li>
+     * </ol>
      *
      * @param authority The organization or party responsible for definition and maintenance
      *                  of the code, or {@code null} if none.
      * @param code      The alphanumeric value identifying an instance in the namespace,
      *                  or {@code null} if none.
+     *
+     * @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
      */
     public DefaultIdentifier(final Citation authority, final String code) {
         this.authority = authority;
         this.code = code;
+        codeSpace = Citations.getCodeSpace(authority);
     }
 
     /**
@@ -209,6 +227,12 @@ public class DefaultIdentifier extends I
 
     /**
      * Returns the alphanumeric value identifying an instance in the namespace.
+     * The code is optionally from a controlled list or pattern.
+     *
+     * <div class="note"><b>Example:</b> {@code "4326"}.</div>
+     *
+     * The code is mandatory according ISO specification, but this {@code DefaultIdentifier}
+     * implementation does not enforce this restriction.
      *
      * @return Value identifying an instance in the namespace.
      */
@@ -230,6 +254,9 @@ public class DefaultIdentifier extends I
 
     /**
      * Returns the identifier or namespace in which the code is valid.
+     * This is often the {@linkplain #getAuthority() authority}'s abbreviation, but not necessarily.
+     *
+     * <div class="note"><b>Example:</b> {@code "EPSG"}.</div>
      *
      * @return The identifier code space, or {@code null} if none.
      *
@@ -258,6 +285,8 @@ public class DefaultIdentifier extends I
      * uses versions. When appropriate, the edition is identified by the effective date,
      * coded using ISO 8601 date format.
      *
+     * <div class="note"><b>Example:</b> the version of the underlying EPSG database.</div>
+     *
      * @return The version, or {@code null} if not available.
      */
     @UML(identifier="version", obligation=OPTIONAL, specification=ISO_19115)
@@ -278,6 +307,8 @@ public class DefaultIdentifier extends I
     /**
      * Returns the natural language description of the meaning of the code value.
      *
+     * <div class="note"><b>Example:</b> "World Geodetic System 1984".</div>
+     *
      * @return The natural language description, or {@code null} if none.
      *
      * @since 0.5
@@ -300,8 +331,9 @@ public class DefaultIdentifier extends I
     }
 
     /**
-     * Organization or party responsible for definition and maintenance of the
-     * {@linkplain #getCode() code}.
+     * Organization or party responsible for definition and maintenance of the {@linkplain #getCode() code}.
+     * The organization's abbreviation is often the same than this identifier {@linkplain #getCodeSpace() code space},
+     * but not necessarily.
      *
      * @return The authority, or {@code null} if not available.
      */
@@ -312,8 +344,7 @@ public class DefaultIdentifier extends I
     }
 
     /**
-     * Sets the organization or party responsible for definition and maintenance of the
-     * {@linkplain #getCode() code}.
+     * Sets the organization or party responsible for definition and maintenance of the {@linkplain #getCode() code}.
      *
      * @param newValue The new authority.
      */

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -19,14 +19,26 @@ package org.apache.sis.metadata.iso.exte
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.InternationalString;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.extent.GeographicDescription;
 import org.apache.sis.metadata.iso.DefaultIdentifier;
+import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.iso.Types;
 
 
 /**
  * Description of the geographic area using identifiers.
+ * The area is given by a {@linkplain #getGeographicIdentifier() geographic identifier},
+ * which may be a code in the codespace of some authority (for example an EPSG code).
+ * In addition, the geographic identifier can optionally have a
+ * {@linkplain DefaultIdentifier#getDescription() natural language description}.
+ *
+ * <div class="note"><b>Example:</b>
+ * a geographic area may be identified by the {@code 1731} code in the {@code EPSG} codespace.
+ * The natural language description for {@code EPSG:1731} can be <cite>“France – mainland north of 48.15°N”</cite>.
+ * </div>
  *
  * <p><b>Limitations:</b></p>
  * <ul>
@@ -41,7 +53,7 @@ import org.apache.sis.metadata.iso.Defau
  * @author  Touraïvane (IRD)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.6
  * @module
  */
 @XmlType(name = "EX_GeographicDescription_Type")
@@ -64,16 +76,57 @@ public class DefaultGeographicDescriptio
     }
 
     /**
-     * Creates an inclusive geographic description initialized to the specified value.
+     * Creates an inclusive geographic description initialized to the given identifier.
      * This constructor sets the {@linkplain #getInclusion() inclusion} property to {@code true}.
      *
+     * <p><b>Usage note:</b> if the description is a sentence like “Netherlands offshore”, it may not be suitable
+     * for the {@code code} argument. Callers may consider using the {@linkplain DefaultIdentifier#getDescription()
+     * identifier description} as an alternative and keep the code for a more compact string (often a primary key).</p>
+     *
+     * <div class="note"><b>Example:</b>
+     * <code>new DefaultGeographicDescription({@link org.apache.sis.metadata.iso.citation.Citations#EPSG}, "1731")</code>
+     * can stand for <cite>“France – mainland north of 48.15°N”</cite>.</div>
+     *
      * @param authority The authority of the identifier code, or {@code null} if none.
      * @param code The identifier code used to represent a geographic area, or {@code null} if none.
      */
     public DefaultGeographicDescription(final Citation authority, final String code) {
         super(true);
         if (authority != null || code != null) {
-            this.geographicIdentifier = new DefaultIdentifier(authority, code);
+            geographicIdentifier = new DefaultIdentifier(authority, code);
+        }
+    }
+
+    /**
+     * Creates an inclusive geographic description initialized to the given natural language description.
+     * This constructor sets the {@linkplain #getInclusion() inclusion} property to {@code true} and the
+     * {@linkplain DefaultIdentifier#getCode() identifier code} to one of the following choices:
+     *
+     * <ul>
+     *   <li>the given {@code description} string if it is a valid
+     *       {@linkplain CharSequences#isUnicodeIdentifier(CharSequence) Unicode identifier},</li>
+     *   <li>otherwise an {@linkplain CharSequences#camelCaseToAcronym(CharSequence) acronym}
+     *       of the given {@code description}.</li>
+     * </ul>
+     *
+     * @param description The natural language description of the meaning of the code value, or {@code null} if none.
+     *
+     * @since 0.6
+     */
+    public DefaultGeographicDescription(final CharSequence description) {
+        super(true);
+        if (description != null) {
+            final DefaultIdentifier id = new DefaultIdentifier();
+            if (CharSequences.isUnicodeIdentifier(description)) {
+                id.setCode(description.toString());
+                if (description instanceof InternationalString) {
+                    id.setDescription((InternationalString) description);
+                }
+            } else {
+                id.setCode(CharSequences.camelCaseToAcronym(description).toString());
+                id.setDescription(Types.toInternationalString(description));
+            }
+            geographicIdentifier = id;
         }
     }
 
@@ -121,6 +174,14 @@ public class DefaultGeographicDescriptio
     /**
      * Returns the identifier used to represent a geographic area.
      *
+     * <div class="note"><b>Example:</b>
+     * an identifier with the following properties:
+     * <ul>
+     *   <li>the {@code "EPSG"} code space,</li>
+     *   <li>the {@code "1731"} code, and</li>
+     *   <li>the <cite>“France – mainland north of 48.15°N”</cite> description.</li>
+     * </ul></div>
+     *
      * @return The identifier used to represent a geographic area, or {@code null}.
      */
     @Override

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -28,6 +28,8 @@ import org.opengis.metadata.extent.Geogr
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.Range;
@@ -54,7 +56,7 @@ import static org.apache.sis.internal.me
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.6
  * @module
  *
  * @see org.apache.sis.geometry.Envelopes
@@ -132,32 +134,60 @@ public final class Extents extends Stati
     }
 
     /**
-     * Returns the union of all vertical ranges found in the given extent, or {@code null} if none.
-     * Depths have negative height values: if the {@linkplain CoordinateSystemAxis#getDirection() axis direction}
+     * Returns the union of chosen vertical ranges found in the given extent, or {@code null} if none.
+     * This method gives preference to heights above the Mean Sea Level when possible.
+     * Depths have negative height values: if the
+     * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getDirection() axis direction}
      * is toward down, then this method reverses the sign of minimum and maximum values.
      *
      * <div class="section">Multi-occurrences</div>
      * If the given {@code Extent} object contains more than one vertical extent, then this method
-     * performs the following choices:
+     * performs a choice based on the vertical datum and the unit of measurement:
      *
      * <ul>
-     *   <li>If no range specify a unit of measurement, return the first range and ignore all others.</li>
-     *   <li>Otherwise take the first range having a unit of measurement. Then:<ul>
-     *     <li>All other ranges having an incompatible unit of measurement will be ignored.</li>
-     *     <li>All other ranges having a compatible unit of measurement will be converted to
-     *         the unit of the first retained range, and their union will be computed.</li>
-     *   </ul></li>
+     *   <li><p><b>Choice based on vertical datum</b><br>
+     *   Only the extents associated (indirectly, through their CRS) to the same non-null {@link VerticalDatumType}
+     *   will be taken in account. If all datum types are null, then this method conservatively uses only the first
+     *   vertical extent. Otherwise the datum type used for filtering the vertical extents is:</p>
+     *
+     *   <ul>
+     *     <li>{@link VerticalDatumType#GEOIDAL} or {@link VerticalDatumType#DEPTH DEPTH} if at least one extent
+     *         uses those datum types. For this method, {@code DEPTH} is considered as equivalent to {@code GEOIDAL}
+     *         except for the axis direction.</li>
+     *     <li>Otherwise, the first non-null datum type found in iteration order.</li>
+     *   </ul>
+     *
+     *   <div class="note"><b>Rational:</b> like {@linkplain #getGeographicBoundingBox(Extent) geographic bounding box},
+     *   the vertical range is an approximative information; the range returned by this method does not carry any
+     *   information about the vertical CRS and this method does not attempt to perform coordinate transformation.
+     *   But this method is more useful if the returned ranges are close to a frequently used surface, like the
+     *   Mean Sea Level. The same simplification is applied in the
+     *   <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#31">{@code VerticalExtent} element of
+     *   Well Known Text (WKT) format</a>, which specifies that <cite>“Vertical extent is an approximate description
+     *   of location; heights are relative to an unspecified mean sea level.”</cite></div></li>
+     *
+     *   <li><p><b>Choice based on units of measurement</b><br>
+     *   If, after the choice based on the vertical datum described above, there is still more than one vertical
+     *   extent to consider, then the next criterion checks for the units of measurement.</p>
+     *   <ul>
+     *     <li>If no range specify a unit of measurement, return the first range and ignore all others.</li>
+     *     <li>Otherwise take the first range having a unit of measurement. Then:<ul>
+     *       <li>All other ranges having an incompatible unit of measurement will be ignored.</li>
+     *       <li>All other ranges having a compatible unit of measurement will be converted to
+     *           the unit of the first retained range, and their union will be computed.</li>
+     *     </ul></li>
+     *   </ul>
+     *
+     *   <div class="note"><b>Example:</b>
+     *   Heights or depths are often measured using some pressure units, for example hectopascals (hPa).
+     *   An {@code Extent} could contain two vertical elements: one with the height measurements in hPa,
+     *   and the other element with heights transformed to metres using an empirical formula.
+     *   In such case this method will select the first vertical element on the assumption that it is
+     *   the "main" one that the metadata producer intended to show. Next, this method will search for
+     *   other vertical elements using pressure unit. In our example there is none, but if such elements
+     *   were found, this method would compute their union.</div></li>
      * </ul>
      *
-     * <div class="note"><b>Example:</b>
-     * Heights or depths are often measured using some pressure units, for example hectopascals (hPa).
-     * An {@code Extent} could contain two vertical elements: one with the height measurements in hPa,
-     * and the other element with heights transformed to metres using an empirical formula.
-     * In such case this method will select the first vertical element on the assumption that it is
-     * the "main" one that the metadata producer intended to show. Next, this method will search for
-     * other vertical elements using pressure unit. In our example there is none, but if such elements
-     * were found, this method would compute their union.</div>
-     *
      * @param  extent The extent to convert to a vertical measurement range, or {@code null}.
      * @return A vertical measurement range created from the given extent, or {@code null} if none.
      *
@@ -165,13 +195,22 @@ public final class Extents extends Stati
      */
     public static MeasurementRange<Double> getVerticalRange(final Extent extent) {
         MeasurementRange<Double> range = null;
+        VerticalDatumType selectedType = null;
         if (extent != null) {
             for (final VerticalExtent element : extent.getVerticalElements()) {
                 double min = element.getMinimumValue();
                 double max = element.getMaximumValue();
                 final VerticalCRS crs = element.getVerticalCRS();
+                VerticalDatumType type = null;
                 Unit<?> unit = null;
                 if (crs != null) {
+                    final VerticalDatum datum = crs.getDatum();
+                    if (datum != null) {
+                        type = datum.getVerticalDatumType();
+                        if (VerticalDatumType.DEPTH.equals(type)) {
+                            type = VerticalDatumType.GEOIDAL;
+                        }
+                    }
                     final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(0);
                     unit = axis.getUnit();
                     if (AxisDirection.DOWN.equals(axis.getDirection())) {
@@ -182,27 +221,39 @@ public final class Extents extends Stati
                 }
                 if (range != null) {
                     /*
-                     * If the new range does not specify any unit, then we do not know how to convert
-                     * the values before to perform the union operation. Conservatively do nothing.
+                     * If the new range does not specify any datum type or unit, then we do not know how to
+                     * convert the values before to perform the union operation. Conservatively do nothing.
                      */
-                    if (unit == null) {
+                    if (type == null || unit == null) {
                         continue;
                     }
                     /*
-                     * If previous range did not specify any unit, then unconditionally replace it by
-                     * the new range since it provides more information. If both ranges specify units,
-                     * then we will compute the union if we can, or ignore the new range otherwise.
+                     * If the new range is not measured relative to the same kind of surface than the previous range,
+                     * then we do not know how to combine those ranges. Do nothing, unless the new range is a Mean Sea
+                     * Level Height in which case we forget all previous ranges and use the new one instead.
                      */
-                    final Unit<?> previous = range.unit();
-                    if (previous != null) {
-                        if (previous.isCompatible(unit)) {
-                            range = (MeasurementRange<Double>) range.union(
-                                    MeasurementRange.create(min, true, max, true, unit));
+                    if (!type.equals(selectedType)) {
+                        if (!type.equals(VerticalDatumType.GEOIDAL)) {
+                            continue;
+                        }
+                    } else if (selectedType != null) {
+                        /*
+                         * If previous range did not specify any unit, then unconditionally replace it by
+                         * the new range since it provides more information. If both ranges specify units,
+                         * then we will compute the union if we can, or ignore the new range otherwise.
+                         */
+                        final Unit<?> previous = range.unit();
+                        if (previous != null) {
+                            if (previous.isCompatible(unit)) {
+                                range = (MeasurementRange<Double>) range.union(
+                                        MeasurementRange.create(min, true, max, true, unit));
+                            }
+                            continue;
                         }
-                        continue;
                     }
                 }
                 range = MeasurementRange.create(min, true, max, true, unit);
+                selectedType = type;
             }
         }
         return range;

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -40,7 +40,7 @@ public final strictfp class ElementTest
     /**
      * A dummy parser to be given to the {@link Element} constructor.
      */
-    private final Parser parser = new Parser(Symbols.SQUARE_BRACKETS, null, null, Locale.ENGLISH) {
+    private final AbstractParser parser = new AbstractParser(Symbols.SQUARE_BRACKETS, null, null, null, Locale.ENGLISH) {
         @Override Object parseObject(Element element) throws ParseException {
             throw new UnsupportedOperationException();
         }
@@ -223,7 +223,7 @@ public final strictfp class ElementTest
         Element element = parse("TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17T00:00:00.0Z]]");
         assertEquals("keyword", "TimeDatum", element.keyword);
         assertEquals("name", "Modified Julian", element.pullString("name"));
-        Element inner = element.pullElement("TimeOrigin");
+        Element inner = element.pullElement(AbstractParser.MANDATORY, "TimeOrigin");
         assertEquals("keyword", "TimeOrigin", inner.keyword);
         assertEquals("date", TestUtilities.date("1858-11-17 00:00:00"), inner.pullDate("date"));
         inner.close(null);

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -16,13 +16,20 @@
  */
 package org.apache.sis.metadata.iso.extent;
 
+import java.util.List;
 import java.util.Arrays;
+import java.util.Collections;
 import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+import javax.measure.converter.UnitConverter;
+import javax.measure.converter.ConversionException;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.apache.sis.measure.Units;
 import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.test.mock.VerticalCRSMock;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
+import org.apache.sis.test.TestUtilities;
 import org.junit.Test;
 
 import static org.apache.sis.internal.metadata.ReferencingServices.NAUTICAL_MILE;
@@ -34,7 +41,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @DependsOn(DefaultGeographicBoundingBoxTest.class)
@@ -46,22 +53,41 @@ public final strictfp class ExtentsTest
 
     /**
      * Tests {@link Extents#getVerticalRange(Extent)}.
+     *
+     * @throws ConversionException should never happen in this test.
      */
     @Test
-    public void testGetVerticalRange() {
-        final DefaultExtent extent = new DefaultExtent();
-        extent.setVerticalElements(Arrays.asList(
+    @SuppressWarnings("null")
+    public void testGetVerticalRange() throws ConversionException {
+        final List<DefaultVerticalExtent> extents = Arrays.asList(
                 new DefaultVerticalExtent( -200,  -100, VerticalCRSMock.HEIGHT),
                 new DefaultVerticalExtent(  150,   300, VerticalCRSMock.DEPTH),
                 new DefaultVerticalExtent(  0.1,   0.2, VerticalCRSMock.SIGMA_LEVEL),
-                new DefaultVerticalExtent( -600,  -300, VerticalCRSMock.HEIGHT_ft), // [91.44 182.88] metres
+                new DefaultVerticalExtent( -600,  -300, VerticalCRSMock.HEIGHT_ft), // [91.44 … 182.88] metres
                 new DefaultVerticalExtent(10130, 20260, VerticalCRSMock.BAROMETRIC_HEIGHT)
-        ));
+        );
+        Collections.shuffle(extents, TestUtilities.createRandomNumberGenerator());
+        /*
+         * Since we have shuffled the vertical extents in random order, the range that we will
+         * test may be either in metres or in feet depending on which vertical extent is first.
+         * So we need to check which linear unit is first.
+         */
+        Unit<?> unit = null;
+        for (final DefaultVerticalExtent e : extents) {
+            unit = e.getVerticalCRS().getCoordinateSystem().getAxis(0).getUnit();
+            if (Units.isLinear(unit)) break;
+        }
+        final UnitConverter c = unit.getConverterToAny(SI.METRE);
+        /*
+         * The actual test. Arbitrarily compare the heights in metres, converting them if needed.
+         */
+        final DefaultExtent extent = new DefaultExtent();
+        extent.setVerticalElements(extents);
         final MeasurementRange<Double> range = Extents.getVerticalRange(extent);
         assertNotNull("getVerticalRange", range);
-        assertEquals("unit", SI.METRE,  range.unit());
-        assertEquals("minimum", -300,   range.getMinDouble(), 0.001);
-        assertEquals("maximum", -91.44, range.getMaxDouble(), 0.001);
+        assertSame   ("unit",    unit,    range.unit());
+        assertEquals ("minimum", -300,    c.convert(range.getMinDouble()), 0.001);
+        assertEquals ("maximum", -91.44,  c.convert(range.getMaxDouble()), 0.001);
     }
 
     /**

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -36,7 +36,7 @@ import org.opengis.util.InternationalStr
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @SuppressWarnings("serial")
@@ -47,31 +47,36 @@ public final strictfp class VerticalCRSM
      * Height in metres.
      */
     public static final VerticalCRS HEIGHT = new VerticalCRSMock("Height",
-            Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true);
+            VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true);
 
     /**
      * Height in feet.
      */
     public static final VerticalCRS HEIGHT_ft = new VerticalCRSMock("Height",
-            Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, NonSI.FOOT, true);
+            VerticalDatumType.GEOIDAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, NonSI.FOOT, true);
 
     /**
      * Height estimated from hPa.
      */
     public static final VerticalCRS BAROMETRIC_HEIGHT = new VerticalCRSMock("Barometric height",
-            0, Double.POSITIVE_INFINITY, SI.MetricPrefix.HECTO(SI.PASCAL), true);
+            VerticalDatumType.BAROMETRIC, 0, Double.POSITIVE_INFINITY, SI.MetricPrefix.HECTO(SI.PASCAL), true);
 
     /**
      * Depth in metres.
      */
     public static final VerticalCRS DEPTH = new VerticalCRSMock("Depth",
-            0, Double.POSITIVE_INFINITY, SI.METRE, false);
+            VerticalDatumType.DEPTH, 0, Double.POSITIVE_INFINITY, SI.METRE, false);
 
     /**
      * Depth as a fraction of the sea floor depth at the location of the point for which the depth is evaluated.
      */
     public static final VerticalCRS SIGMA_LEVEL = new VerticalCRSMock("Sigma level",
-            0, 1, Unit.ONE, false);
+            VerticalDatumType.OTHER_SURFACE, 0, 1, Unit.ONE, false);
+
+    /**
+     * The datum type (geoidal, barometric, etc.).
+     */
+    private final VerticalDatumType type;
 
     /**
      * The minimum and maximum values.
@@ -97,10 +102,11 @@ public final strictfp class VerticalCRSM
      * @param minimumValue The minium value.
      * @param maximumValue The maximum value.
      */
-    private VerticalCRSMock(final String name, final double minimumValue, final double maximumValue,
-            final Unit<?> unit, final boolean up)
+    private VerticalCRSMock(final String name, VerticalDatumType type,
+            final double minimumValue, final double maximumValue, final Unit<?> unit, final boolean up)
     {
         super(name);
+        this.type         = type;
         this.minimumValue = minimumValue;
         this.maximumValue = maximumValue;
         this.unit         = unit;
@@ -120,7 +126,7 @@ public final strictfp class VerticalCRSM
     @Override public InternationalString  getAnchorPoint()       {return null;}
     @Override public Date                 getRealizationEpoch()  {return null;}
     @Override public Extent               getDomainOfValidity()  {return null;}
-    @Override public VerticalDatumType    getVerticalDatumType() {return VerticalDatumType.GEOIDAL;}
+    @Override public VerticalDatumType    getVerticalDatumType() {return type;}
     @Override public VerticalDatum        getDatum()             {return this;}
     @Override public VerticalCS           getCoordinateSystem()  {return this;}
     @Override public int                  getDimension()         {return 1;}

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -446,6 +446,18 @@ public final class ServicesForMetadata e
     ///////////////////////////////////////////////////////////////////////////////////////
 
     /**
+     * Returns a coordinate reference system for heights above the mean seal level.
+     *
+     * @return The "Mean Seal Level (MSL) height" coordinate reference system.
+     *
+     * @since 0.6
+     */
+    @Override
+    public VerticalCRS getMSLH() {
+        return CommonCRS.Vertical.MEAN_SEA_LEVEL.crs();
+    }
+
+    /**
      * Returns the Greenwich prime meridian.
      *
      * @return The Greenwich prime meridian.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -780,7 +780,9 @@ public class AbstractIdentifiedObject ex
      * </ul>
      *
      * <div class="section">Future evolutions</div>
-     * This method implements heuristic rules learned from experience while trying to provide inter-operability
+     * This method implements recommendations from the
+     * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#139">§B.5.2 of WKT 2 specification</a>,
+     * together with heuristic rules learned from experience while trying to provide inter-operability
      * with different data producers. Those rules may be adjusted in any future SIS version according experience
      * gained while working with more data producers.
      *
@@ -788,6 +790,7 @@ public class AbstractIdentifiedObject ex
      * @return {@code true} if the primary name of at least one alias matches the specified {@code name}.
      *
      * @see IdentifiedObjects#isHeuristicMatchForName(IdentifiedObject, String)
+     * @see org.apache.sis.util.Characters.Filter#LETTERS_AND_DIGITS
      */
     public boolean isHeuristicMatchForName(final String name) {
         return NameToIdentifier.isHeuristicMatchForName(this.name, alias, name);

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -28,6 +28,7 @@ import org.opengis.referencing.cs.Ellips
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.crs.CRSFactory;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -42,6 +43,7 @@ import org.opengis.metadata.extent.Geogr
 import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.referencing.cs.DefaultVerticalCS;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
@@ -82,7 +84,7 @@ import static java.util.Collections.sing
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public final class CRS extends Static {
@@ -164,7 +166,7 @@ public final class CRS extends Static {
          * that CommonCRS is not expected to succeed if the real EPSG factory threw an exception,
          * so we will log a message at the warning level in such case.
          */
-        CRSAuthorityFactory factory = null; // TODO
+        final CRSAuthorityFactory factory = DefaultFactories.forClass(CRSAuthorityFactory.class);
         if (factory != null) try {
             return factory.createCoordinateReferenceSystem(value);
         } catch (FactoryException failure) {
@@ -177,6 +179,62 @@ public final class CRS extends Static {
     }
 
     /**
+     * Creates a Coordinate Reference System object from a <cite>Well Known Text</cite> (WKT).
+     * The default {@linkplain org.apache.sis.io.wkt Apache SIS parser} understands both
+     * version 1 (a.k.a. OGC 01-009) and version 2 (a.k.a. ISO 19162) of the WKT format.
+     *
+     * <div class="note"><b>Example:</b> below is a slightly simplified WKT 2 string for a Mercator projection.
+     * For making this example smaller, some optional {@code UNIT[…]} and {@code ORDER[…]} elements have been omitted.
+     *
+     * {@preformat wkt
+     *   ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
+     *     BaseGeodCRS["SIRGAS 2000",
+     *       Datum["Sistema de Referencia Geocentrico para las Americas 2000",
+     *         Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
+     *     Conversion["Petrobras Mercator",
+     *       Method["Mercator (variant B)", Id["EPSG",9805]],
+     *       Parameter["Latitude of 1st standard parallel", -2],
+     *       Parameter["Longitude of natural origin", -43],
+     *       Parameter["False easting", 5000000],
+     *       Parameter["False northing", 10000000]],
+     *     CS[cartesian,2],
+     *       Axis["easting (E)", east],
+     *       Axis["northing (N)", north],
+     *       LengthUnit["metre", 1],
+     *     Id["EPSG",5641]]
+     * }
+     * </div>
+     *
+     * <div class="section">Usage and performance considerations</div>
+     * This convenience method delegates to
+     * {@link org.apache.sis.referencing.factory.GeodeticObjectFactory#createFromWKT(String)}
+     * using a default factory instance. This is okay for occasional use, but has the following limitations:
+     *
+     * <ul>
+     *   <li>Performance may be sub-optimal in a multi-thread environment.</li>
+     *   <li>No control on the WKT {@linkplain org.apache.sis.io.wkt.Convention conventions} in use.</li>
+     *   <li>No control on the handling of {@linkplain org.apache.sis.io.wkt.Warnings warnings}.</li>
+     * </ul>
+     *
+     * Applications which need to parse a large amount of WKT strings should consider to use
+     * the {@link org.apache.sis.io.wkt.WKTFormat} class instead than this method.
+     *
+     * @param  text Coordinate system encoded in Well-Known Text format (version 1 or 2).
+     * @return The parsed Coordinate Reference System.
+     * @throws FactoryException if the given WKT can not be parsed.
+     *
+     * @see org.apache.sis.io.wkt
+     * @see org.apache.sis.geometry.Envelopes#fromWKT(CharSequence)
+     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
+     *
+     * @since 0.6
+     */
+    public static CoordinateReferenceSystem fromWKT(final String text) throws FactoryException {
+        ArgumentChecks.ensureNonNull("text", text);
+        return DefaultFactories.forBuildin(CRSFactory.class).createFromWKT(text);
+    }
+
+    /**
      * Returns the valid geographic area for the given coordinate reference system, or {@code null} if unknown.
      * This method explores the {@linkplain CoordinateReferenceSystem#getDomainOfValidity() domain of validity}
      * associated with the given CRS. If more than one geographic bounding box is found, then they will be

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -36,6 +36,7 @@ import org.apache.sis.referencing.Identi
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.AbstractCS;
 import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.Utilities.deepEquals;
@@ -520,10 +521,12 @@ public class AbstractCRS extends Abstrac
             formatter.append(toFormattable(cs)); // WKT2 only, since the concept of CoordinateSystem was not explicit in WKT 1.
             formatter.indent(+1);
         }
-        final int dimension = cs.getDimension();
-        for (int i=0; i<dimension; i++) {
-            formatter.newLine();
-            formatter.append(toFormattable(cs.getAxis(i)));
+        if (!isWKT1 || formatter.getConvention() != Convention.WKT1_IGNORE_AXES) {
+            final int dimension = cs.getDimension();
+            for (int i=0; i<dimension; i++) {
+                formatter.newLine();
+                formatter.append(toFormattable(cs.getAxis(i)));
+            }
         }
         if (!isWKT1) { // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
             formatter.newLine();

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -143,8 +143,8 @@ public enum AxesConvention implements Ax
      * changes are more difficult to handle by coordinate operation factories.
      * </div>
      *
-     * @see CoordinateSystems#normalize(CoordinateSystem)
      * @see org.apache.sis.referencing.CommonCRS#normalizedGeographic()
+     * @see CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)
      */
     NORMALIZED {
         @Override

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -43,12 +43,12 @@ import org.apache.sis.referencing.datum.
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.MergedProperties;
 import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.metadata.WKTParser;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.collection.WeakHashSet;
 import org.apache.sis.util.iso.AbstractFactory;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.io.wkt.Parser;
 import org.apache.sis.xml.XML;
 
 
@@ -180,14 +180,14 @@ import org.apache.sis.xml.XML;
  * @version 0.6
  * @module
  */
-public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory {
+public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser {
     /**
      * The constructor for WKT parsers, fetched when first needed. The WKT parser is defined in the
      * same module than this class, so we will hopefully not have security issues.  But we have to
      * use reflection because the parser class is not yet public (because we do not want to commit
      * its API yet).
      */
-    private static volatile Constructor<? extends WKTParser> parserConstructor;
+    private static volatile Constructor<? extends Parser> parserConstructor;
 
     /**
      * The default properties, or an empty map if none. This map shall not change after construction in
@@ -214,7 +214,7 @@ public class GeodeticObjectFactory exten
      * The <cite>Well Known Text</cite> parser for {@code CoordinateReferenceSystem} instances.
      * This parser is not thread-safe, so we need to prevent two threads from using the same instance in same time.
      */
-    private final AtomicReference<WKTParser> parser;
+    private final AtomicReference<Parser> parser;
 
     /**
      * Constructs a factory with no default properties.
@@ -238,7 +238,7 @@ public class GeodeticObjectFactory exten
         }
         defaultProperties = properties;
         pool = new WeakHashSet<IdentifiedObject>(IdentifiedObject.class);
-        parser = new AtomicReference<WKTParser>();
+        parser = new AtomicReference<Parser>();
     }
 
     /**
@@ -1340,18 +1340,55 @@ public class GeodeticObjectFactory exten
     }
 
     /**
-     * Creates a coordinate reference system object from a string.
+     * Creates a Coordinate Reference System object from a <cite>Well Known Text</cite> (WKT).
+     * This method understands both version 1 (a.k.a. OGC 01-009) and version 2 (a.k.a. ISO 19162)
+     * of the WKT format.
+     *
+     * <div class="note"><b>Example:</b> below is a slightly simplified WKT 2 string for a Mercator projection.
+     * For making this example smaller, some optional {@code UNIT[…]} and {@code ORDER[…]} elements have been omitted.
+     *
+     * {@preformat wkt
+     *   ProjectedCRS["SIRGAS 2000 / Brazil Mercator",
+     *     BaseGeodCRS["SIRGAS 2000",
+     *       Datum["Sistema de Referencia Geocentrico para las Americas 2000",
+     *         Ellipsoid["GRS 1980", 6378137, 298.257222101]]],
+     *     Conversion["Petrobras Mercator",
+     *       Method["Mercator (variant B)", Id["EPSG",9805]],
+     *       Parameter["Latitude of 1st standard parallel", -2],
+     *       Parameter["Longitude of natural origin", -43],
+     *       Parameter["False easting", 5000000],
+     *       Parameter["False northing", 10000000]],
+     *     CS[cartesian,2],
+     *       Axis["easting (E)", east],
+     *       Axis["northing (N)", north],
+     *       LengthUnit["metre", 1],
+     *     Id["EPSG",5641]]
+     * }
+     * </div>
+     *
+     * <div class="section">Usage and performance considerations</div>
+     * The default implementation uses a shared instance of {@link org.apache.sis.io.wkt.WKTFormat}
+     * with the addition of thread-safety. This is okay for occasional use,
+     * but is sub-optimal if this method is extensively used in a multi-thread environment.
+     * Furthermore this method offers no control on the WKT {@linkplain org.apache.sis.io.wkt.Convention conventions}
+     * in use and on the handling of {@linkplain org.apache.sis.io.wkt.Warnings warnings}.
+     * Applications which need to parse a large amount of WKT strings should consider to use
+     * the {@link org.apache.sis.io.wkt.WKTFormat} class instead than this method.
      *
      * @param  text Coordinate system encoded in Well-Known Text format (version 1 or 2).
      * @throws FactoryException if the object creation failed.
+     *
+     * @see org.apache.sis.io.wkt
+     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
+     * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
      */
     @Override
     public CoordinateReferenceSystem createFromWKT(final String text) throws FactoryException {
-        WKTParser p = parser.getAndSet(null);
+        Parser p = parser.getAndSet(null);
         if (p == null) try {
-            Constructor<? extends WKTParser> c = parserConstructor;
+            Constructor<? extends Parser> c = parserConstructor;
             if (c == null) {
-                c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(WKTParser.class)
+                c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(Parser.class)
                          .getConstructor(Map.class, ObjectFactory.class, MathTransformFactory.class);
                 c.setAccessible(true);
                 parserConstructor = c;

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -46,9 +46,9 @@ import org.opengis.referencing.operation
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
 
+import org.apache.sis.io.wkt.Parser;
 import org.apache.sis.internal.util.LazySet;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.metadata.WKTParser;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
@@ -155,7 +155,7 @@ import org.apache.sis.internal.jdk8.JDK8
  * @see MathTransformProvider
  * @see AbstractMathTransform
  */
-public class DefaultMathTransformFactory extends AbstractFactory implements MathTransformFactory {
+public class DefaultMathTransformFactory extends AbstractFactory implements MathTransformFactory, Parser {
     /*
      * NOTE FOR JAVADOC WRITER:
      * The "method" word is ambiguous here, because it can be "Java method" or "coordinate operation method".
@@ -177,7 +177,7 @@ public class DefaultMathTransformFactory
      * use reflection because the parser class is not yet public (because we do not want to commit
      * its API yet).
      */
-    private static volatile Constructor<? extends WKTParser> parserConstructor;
+    private static volatile Constructor<? extends Parser> parserConstructor;
 
     /**
      * All methods specified at construction time or found on the classpath.
@@ -221,7 +221,7 @@ public class DefaultMathTransformFactory
      * This parser is not thread-safe, so we need to prevent two threads from using
      * the same instance in same time.
      */
-    private final AtomicReference<WKTParser> parser;
+    private final AtomicReference<Parser> parser;
 
     /**
      * Creates a new factory which will discover operation methods with a {@link ServiceLoader}.
@@ -293,7 +293,7 @@ public class DefaultMathTransformFactory
         methodsByType = new IdentityHashMap<Class<?>, OperationMethodSet>();
         lastMethod    = new ThreadLocal<OperationMethod>();
         pool          = new WeakHashSet<MathTransform>(MathTransform.class);
-        parser        = new AtomicReference<WKTParser>();
+        parser        = new AtomicReference<Parser>();
     }
 
     /**
@@ -823,11 +823,11 @@ public class DefaultMathTransformFactory
     @Override
     public MathTransform createFromWKT(final String text) throws FactoryException {
         lastMethod.remove();
-        WKTParser p = parser.getAndSet(null);
+        Parser p = parser.getAndSet(null);
         if (p == null) try {
-            Constructor<? extends WKTParser> c = parserConstructor;
+            Constructor<? extends Parser> c = parserConstructor;
             if (c == null) {
-                c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(WKTParser.class)
+                c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(Parser.class)
                          .getConstructor(MathTransformFactory.class);
                 c.setAccessible(true);
                 parserConstructor = c;

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -18,6 +18,7 @@ package org.apache.sis.io.wkt;
 
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Locale;
 import java.text.ParsePosition;
 import java.text.ParseException;
 import javax.measure.unit.SI;
@@ -68,6 +69,9 @@ public final strictfp class GeodeticObje
     /**
      * Parses the given text.
      *
+     * @param  type The expected object type.
+     * @param  text The WKT string to parse.
+     * @return The parsed object.
      * @throws ParseException if an error occurred during the parsing.
      */
     private <T> T parse(final Class<T> type, final String text) throws ParseException {
@@ -78,6 +82,8 @@ public final strictfp class GeodeticObje
         final Object obj = parser.parseObject(text, position);
         assertEquals("errorIndex", -1, position.getErrorIndex());
         assertEquals("index", text.length(), position.getIndex());
+        assertNull("warnings", parser.getAndClearWarnings(obj));
+        assertTrue("ignoredElements", parser.ignoredElements.isEmpty());
         assertInstanceOf("GeodeticObjectParser.parseObject", type, obj);
         return type.cast(obj);
     }
@@ -85,9 +91,9 @@ public final strictfp class GeodeticObje
     /**
      * Uses a new parser for the given convention.
      */
-    private void setConvention(final Convention convention, final boolean isAxisIgnored) {
+    private void setConvention(final Convention convention) {
         final GeodeticObjectParser p = parser;
-        parser = new GeodeticObjectParser(p.symbols, null, null, convention, isAxisIgnored, p.errorLocale, null);
+        parser = new GeodeticObjectParser(p.symbols, null, null, null, convention, p.errorLocale, null);
     }
 
     /**
@@ -343,7 +349,7 @@ public final strictfp class GeodeticObje
          * So we allow this interpretation in Convention.WKT1_COMMON_UNITS for compatibility reasons.
          */
         wkt = wkt.replace("2.5969213", "2.33722917");   // Convert unit in prime meridian.
-        setConvention(Convention.WKT1_COMMON_UNITS, true);
+        setConvention(Convention.WKT1_IGNORE_AXES);
         crs = parse(GeographicCRS.class, wkt);
         assertNameAndIdentifierEqual("NTF (Paris)", 0, crs);
         pm = verifyNTF(crs.getDatum(), false);
@@ -397,7 +403,7 @@ public final strictfp class GeodeticObje
         wkt = wkt.replace("52.0",      "46.8");             // Convert unit in “latitude_of_origin” parameter.
         wkt = wkt.replace("600.0",     "600000");           // Convert unit in “false_easting” parameter.
         wkt = wkt.replace("2200.0",    "2200000");          // Convert unit in “false_northing” parameter.
-        setConvention(Convention.WKT1_COMMON_UNITS, true);
+        setConvention(Convention.WKT1_IGNORE_AXES);
         crs = parse(ProjectedCRS.class, wkt);
         assertNameAndIdentifierEqual("NTF (Paris) / Lambert zone II", 0, crs);
         verifyProjectedCS(crs.getCoordinateSystem(), SI.KILOMETRE);
@@ -620,4 +626,61 @@ public final strictfp class GeodeticObje
         assertEquals("false_easting",      600000.0, param.parameter("false_easting"     ).doubleValue(SI   .METRE),        STRICT);
         assertEquals("false_northing",     200000.0, param.parameter("false_northing"    ).doubleValue(SI   .METRE),        STRICT);
     }
+
+    /**
+     * Tests the production of a warning messages when the WKT contains unknown elements.
+     *
+     * @throws ParseException if the parsing failed.
+     */
+    @Test
+    @DependsOnMethod("testWithImplicitAxes")
+    public void testWarnings() throws ParseException {
+        parser = new GeodeticObjectParser();
+        final ParsePosition position = new ParsePosition(0);
+        final GeographicCRS crs = (GeographicCRS) parser.parseObject(
+               "  GEOGCS[“WGS 84”,\n" +
+               "    DATUM[“World Geodetic System 1984”,\n" +
+               "      SPHEROID[“WGS84”, 6378137.0, 298.257223563, Ext1[“foo”], Ext2[“bla”]]],\n" +
+               "      PRIMEM[“Greenwich”, 0.0, Intruder[“unknown”]],\n" +
+               "    UNIT[“degree”, 0.017453292519943295], Intruder[“foo”]]", position);
+
+        verifyGeographicCRS(0, crs);
+        assertEquals("errorIndex", -1, position.getErrorIndex());
+        final Warnings warnings = parser.getAndClearWarnings(crs);
+        assertNotNull("warnings", warnings);
+
+        assertTrue("warnings.getExceptions()",
+                warnings.getExceptions().isEmpty());
+
+        assertEquals("warnings.getRootElement()", "WGS 84",
+                warnings.getRootElement());
+
+        assertArrayEquals("warnings.getUnknownElements()",
+                new String[] {"Intruder", "Ext1", "Ext2"},
+                warnings.getUnknownElements().toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"PRIMEM", "GEOGCS"},
+                warnings.getUnknownElementLocations("Intruder").toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"SPHEROID"},
+                warnings.getUnknownElementLocations("Ext1").toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"SPHEROID"},
+                warnings.getUnknownElementLocations("Ext2").toArray());
+
+        assertMultilinesEquals("Parsing of “WGS 84” done, but some elements were ignored.\n" +
+                               " • The text contains unknown elements:\n" +
+                               "    ‣ “Intruder” in PRIMEM, GEOGCS.\n" +
+                               "    ‣ “Ext1” in SPHEROID.\n" +
+                               "    ‣ “Ext2” in SPHEROID.\n", warnings.toString(Locale.US));
+
+        assertMultilinesEquals("La lecture de « WGS 84 » a été faite, mais en ignorant certains éléments.\n" +
+                               " • Le texte contient des éléments inconnus :\n" +
+                               "    ‣ « Intruder » dans PRIMEM, GEOGCS.\n" +
+                               "    ‣ « Ext1 » dans SPHEROID.\n" +
+                               "    ‣ « Ext2 » dans SPHEROID.\n", warnings.toString(Locale.FRANCE));
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -123,7 +123,7 @@ public final strictfp class AbstractRefe
                 "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
                 "  VerticalExtent[-1000, -10, LengthUnit[“metre”, 1]],\n" +
                 "  Id[“EPSG”, 4326, “8.2”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
-                "  Remarks[“注です。”]]",
+                "  Remark[“注です。”]]",
                 object);
 
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
@@ -133,7 +133,7 @@ public final strictfp class AbstractRefe
                 "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
                 "  VerticalExtent[-1000, -10],\n" +
                 "  Id[“EPSG”, 4326, “8.2”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
-                "  Remarks[“注です。”]]",
+                "  Remark[“注です。”]]",
                 object);
 
         assertWktEquals(Convention.INTERNAL,
@@ -143,7 +143,7 @@ public final strictfp class AbstractRefe
                 "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
                 "  VerticalExtent[-1000, -10],\n" +
                 "  Id[“EPSG”, 4326, “8.2”],\n" +
-                "  Remarks[“注です。”]]",
+                "  Remark[“注です。”]]",
                 object);
     }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -158,7 +158,7 @@ public final strictfp class DefaultCompo
                 "    AXIS[“Gravity-related height”, UP]],\n" +
                 "  TIMECRS[“Time”,\n" +
                 "    TIMEDATUM[“Modified Julian”, TIMEORIGIN[1858-11-17T00:00:00.0Z]],\n" +
-                "    UNIT[“day”, 86400],\n" +
+                "    TIMEUNIT[“day”, 86400],\n" +
                 "    AXIS[“Time”, FUTURE]]]",
                 HardCodedCRS.GEOID_4D);
     }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -41,7 +41,7 @@ public final strictfp class DefaultTempo
         assertWktEquals(Convention.WKT1,
                 "TIMECRS[“Time”,\n" +
                 "  TIMEDATUM[“Modified Julian”, TIMEORIGIN[1858-11-17T00:00:00.0Z]],\n" +
-                "  UNIT[“day”, 86400],\n" +
+                "  TIMEUNIT[“day”, 86400],\n" +
                 "  AXIS[“Time”, FUTURE]]",
                 HardCodedCRS.TIME);
     }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -274,13 +274,13 @@ public final strictfp class DefaultGeode
         assertWktEquals(Convention.INTERNAL,
                 "Datum[“World Geodetic System 1984”,\n" +
                 "  Ellipsoid[“WGS 84”, 6378137.0, 298.257223563, Id[“EPSG”, 7030],\n" +
-                "    Remarks[“Defining parameters cited in EPSG database.”]],\n" +
+                "    Remark[“Defining parameters cited in EPSG database.”]],\n" +
                 "  Anchor[“Station coordinates changed by a few centimetres in 1994, 1997, 2002 and 2012.”],\n" +
                 "  Scope[“Satellite navigation.”],\n" +
                 "  Area[“World.”],\n" +
                 "  BBox[-90.00, -180.00, 90.00, 180.00],\n" +
                 "  Id[“EPSG”, 6326],\n" +
-                "  Remarks[“No distinction between the original and subsequent WGS 84 frames.”]]",
+                "  Remark[“No distinction between the original and subsequent WGS 84 frames.”]]",
                 datum);
     }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -153,7 +153,7 @@ public final strictfp class DefaultPrime
                 "PrimeMeridian[“Paris”, 2.5969213, AngleUnit[“grade”, 0.015707963267948967], Id[“EPSG”, 8903, URI[“urn:ogc:def:meridian:EPSG::8903”]]]", pm);
         assertWktEquals(Convention.INTERNAL,
                 "PrimeMeridian[“Paris”, 2.5969213, Unit[“grade”, 0.015707963267948967], Id[“EPSG”, 8903],\n" +
-                "  Remarks[“Equivalent to 2°20′14.025″.”]]", pm);
+                "  Remark[“Equivalent to 2°20′14.025″.”]]", pm);
         assertXmlEquals(
                 "<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
                 "  <gml:identifier codeSpace=\"IOGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>\n" +

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -166,12 +166,12 @@ public final class Units extends Static
      *
      * @see #isAngular(Unit)
      */
-    @SuppressWarnings({"unchecked","rawtypes"})
+    @SuppressWarnings("unchecked")
     public static Unit<Angle> ensureAngular(final Unit<?> unit) throws IllegalArgumentException {
         if (unit != null && !isAngular(unit)) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.NonAngularUnit_1, unit));
         }
-        return (Unit) unit;
+        return (Unit<Angle>) unit;
     }
 
     /**
@@ -184,12 +184,12 @@ public final class Units extends Static
      *
      * @see #isLinear(Unit)
      */
-    @SuppressWarnings({"unchecked","rawtypes"})
+    @SuppressWarnings("unchecked")
     public static Unit<Length> ensureLinear(final Unit<?> unit) throws IllegalArgumentException {
         if (unit != null && !isLinear(unit)) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.NonLinearUnit_1, unit));
         }
-        return (Unit) unit;
+        return (Unit<Length>) unit;
     }
 
     /**
@@ -202,12 +202,12 @@ public final class Units extends Static
      *
      * @see #isTemporal(Unit)
      */
-    @SuppressWarnings({"unchecked","rawtypes"})
+    @SuppressWarnings("unchecked")
     public static Unit<Duration> ensureTemporal(final Unit<?> unit) throws IllegalArgumentException {
         if (unit != null && !isTemporal(unit)) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.NonTemporalUnit_1, unit));
         }
-        return (Unit) unit;
+        return (Unit<Duration>) unit;
     }
 
     /**
@@ -220,12 +220,12 @@ public final class Units extends Static
      *
      * @see #isScale(Unit)
      */
-    @SuppressWarnings({"unchecked","rawtypes"})
+    @SuppressWarnings("unchecked")
     public static Unit<Dimensionless> ensureScale(final Unit<?> unit) throws IllegalArgumentException {
         if (unit != null && !isScale(unit)) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.NonScaleUnit_1, unit));
         }
-        return (Unit) unit;
+        return (Unit<Dimensionless>) unit;
     }
 
     /**
@@ -248,14 +248,14 @@ public final class Units extends Static
      * @return The unit multiplied by the given factor.
      */
     @Workaround(library="JSR-275", version="0.9.3")
-    @SuppressWarnings({"unchecked","rawtypes"})
+    @SuppressWarnings("unchecked")
     public static <A extends Quantity> Unit<A> multiply(Unit<A> unit, final double factor) {
         if (SI.RADIAN.equals(unit)) {
             if (abs(factor - (PI / 180)) <= (EPS * PI/180)) {
-                return (Unit) NonSI.DEGREE_ANGLE;
+                return (Unit<A>) NonSI.DEGREE_ANGLE;
             }
             if (abs(factor - (PI / 200)) <= (EPS * PI/200)) {
-                return (Unit) NonSI.GRADE;
+                return (Unit<A>) NonSI.GRADE;
             }
         }
         if (abs(factor - 1) > EPS) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util;
 
+import org.opengis.metadata.citation.Citation;  // For javadoc.
 import org.apache.sis.util.resources.Errors;
 
 
@@ -263,6 +264,21 @@ public final class Characters extends St
      * in this class. Then, Unicode characters can be tested for inclusion in the subset by
      * calling the {@link #contains(int)} method.</p>
      *
+     * <div class="section">Relationship with international standards</div>
+     * ISO 19162:2015 §B.5.2 recommends to ignore spaces, case and the following characters when comparing two
+     * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() identified object names}:
+     * “{@code _}” (underscore), “{@code -}” (minus sign), “{@code /}” (solidus),
+     * “{@code (}” (left parenthesis) and “{@code )}” (right parenthesis).
+     * The same specification also limits the set of valid characters in a name to the following (§6.3.1):
+     *
+     * <blockquote>{@code A-Z a-z 0-9 _ [ ] ( ) { } < = > . , : ; + - (space) % & ' " * ^ / \ ? | °}</blockquote>
+     * <div class="note"><b>Note:</b> SIS does not enforce this restriction in its programmatic API,
+     * but may perform some character substitutions at <cite>Well Known Text</cite> (WKT) formatting time.</div>
+     *
+     * If we take only the characters in the above list which are valid in a {@linkplain #UNICODE_IDENTIFIER
+     * Unicode identifier} and remove the characters that ISO 19162 recommends to ignore, the only characters
+     * left are {@linkplain #LETTERS_AND_DIGITS letters and digits}.
+     *
      * @author  Martin Desruisseaux (Geomatys)
      * @since   0.3
      * @version 0.3
@@ -270,6 +286,7 @@ public final class Characters extends St
      *
      * @see java.lang.Character.Subset
      * @see Character#getType(int)
+     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#139">WKT 2 specification</a>
      */
     public static class Filter extends Character.Subset {
         /*
@@ -281,12 +298,23 @@ public final class Characters extends St
         /**
          * The subset of all characters for which {@link Character#isLetterOrDigit(int)}
          * returns {@code true}. This subset includes the following general categories:
+         *
+         * <blockquote>
          * {@link Character#LOWERCASE_LETTER},
          * {@link Character#UPPERCASE_LETTER     UPPERCASE_LETTER},
          * {@link Character#TITLECASE_LETTER     TITLECASE_LETTER},
          * {@link Character#MODIFIER_LETTER      MODIFIER_LETTER},
          * {@link Character#OTHER_LETTER         OTHER_LETTER} and
          * {@link Character#DECIMAL_DIGIT_NUMBER DECIMAL_DIGIT_NUMBER}.
+         * </blockquote>
+         *
+         * SIS uses this filter when comparing two
+         * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() identified object names}.
+         * See the <cite>Relationship with international standards</cite> section in this class javadoc
+         * for more information.
+         *
+         * @see org.apache.sis.referencing.AbstractIdentifiedObject#isHeuristicMatchForName(String)
+         * @see org.apache.sis.metadata.iso.citation.Citations#identifierMatches(Citation, String)
          */
         public static final Filter LETTERS_AND_DIGITS = new LettersAndDigits();
 
@@ -295,10 +323,13 @@ public final class Characters extends St
          * returns {@code true}, excluding {@linkplain Character#isIdentifierIgnorable(int) ignorable} characters.
          * This subset includes all the {@link #LETTERS_AND_DIGITS} categories with the addition of the following
          * ones:
+         *
+         * <blockquote>
          * {@link Character#LETTER_NUMBER},
          * {@link Character#CONNECTOR_PUNCTUATION CONNECTOR_PUNCTUATION},
          * {@link Character#NON_SPACING_MARK NON_SPACING_MARK} and
          * {@link Character#COMBINING_SPACING_MARK COMBINING_SPACING_MARK}.
+         * </blockquote>
          */
         public static final Filter UNICODE_IDENTIFIER = new UnicodeIdentifier();
 

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -921,9 +921,9 @@ public final class Errors extends Indexe
         public static final short UnknownFormatFor_1 = 115;
 
         /**
-         * Keyword “{1}” in element “{0}” is unknown.
+         * Keyword “{0}” is unknown.
          */
-        public static final short UnknownKeywordInElement_2 = 192;
+        public static final short UnknownKeyword_1 = 192;
 
         /**
          * Option “{0}” is not recognized.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Thu Jun 18 17:38:16 2015
@@ -195,7 +195,7 @@ UnknownAxisDirection_1            = Axis
 UnknownCommand_1                  = Command \u201c{0}\u201d is not recognized.
 UnknownEnumValue_2                = \u201c{1}\u201d is not a known or supported value for the \u2018{0}\u2019 enumeration.
 UnknownFormatFor_1                = Format of \u201c{0}\u201d is not recognized.
-UnknownKeywordInElement_2         = Keyword \u201c{1}\u201d in element \u201c{0}\u201d is unknown.
+UnknownKeyword_1                  = Keyword \u201c{0}\u201d is unknown.
 UnknownOption_1                   = Option \u201c{0}\u201d is not recognized.
 UnknownType_1                     = Type \u2018{0}\u2019 is unknown in this context.
 UnknownTypeForProperty_1          = Type of the \u201c{0}\u201d property is unknown.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu Jun 18 17:38:16 2015
@@ -14,6 +14,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+#
+# Punctuation rules in French (source: http://unicode.org/udhr/n/notes_fra.html)
+#
+#   U+202F NARROW NO-BREAK SPACE  before  ; ! and ?
+#   U+00A0 NO-BREAK SPACE         before  :
+#
 AbstractType_1                    = Le type \u2018{0}\u2019 est abstrait.
 AmbiguousName_3                   = Le nom \u00ab\u202f{2}\u202f\u00bb est ambigu\u00eb car il peut \u00eatre interpr\u00e9t\u00e9 comme \u00ab\u202f{0}\u202f\u00bb ou \u00ab\u202f{1}\u202f\u00bb.
 CanNotAddToExclusiveSet_2         = Aucun \u00e9l\u00e9ment ne peut \u00eatre ajout\u00e9 \u00e0 cet ensemble car les propri\u00e9t\u00e9s \u2018{0}\u2019 et \u2018{1}\u2019 sont mutuellement exclusives.
@@ -184,7 +191,7 @@ UnknownAxisDirection_1            = La d
 UnknownCommand_1                  = La commande \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
 UnknownEnumValue_2                = \u00ab\u202f{1}\u202f\u00bb n\u2019est pas une valeur connue ou support\u00e9e pour l\u2019\u00e9num\u00e9ration \u2018{0}\u2019.
 UnknownFormatFor_1                = Le format de \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnu.
-UnknownKeywordInElement_2         = Le mot-cl\u00e9 \u00ab\u202f{1}\u202f\u00bb dans l\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnu.
+UnknownKeyword_1                  = Le mot-cl\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnu.
 UnknownOption_1                   = L\u2019option \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue.
 UnknownType_1                     = Le type \u2018{0}\u2019 n\u2019est pas reconnu dans ce contexte.
 UnknownTypeForProperty_1          = Le type de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb est inconnu.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -93,6 +93,11 @@ public final class Messages extends Inde
         public static final short IgnoredPropertyAssociatedTo_1 = 7;
 
         /**
+         * {0,choice,0#Formatting|1#Parsing} of “{1}” done, but some elements were ignored.
+         */
+        public static final short IncompleteFormattingOrParsing_2 = 14;
+
+        /**
          * Text were discarded for some locales.
          */
         public static final short LocalesDiscarded = 3;
@@ -120,6 +125,11 @@ public final class Messages extends Inde
         public static final short PropertyHiddenBy_2 = 4;
 
         /**
+         * The text contains unknown elements:
+         */
+        public static final short UnknownElementsInText = 13;
+
+        /**
          * Can not parse “{1}” as an instance of ‘{0}’. The value is stored as plain text instead, but
          * will be ignored by some processing.
          */

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] Thu Jun 18 17:38:16 2015
@@ -21,9 +21,11 @@ ConstantProjParameterValue_1    = This p
 DiscardedExclusiveProperty_2    = Property \u201c{0}\u201d has been discarded in favor of \u201c{1}\u201d, because those two properties are mutually exclusive.
 IgnoredPropertiesAfterFirst_1   = Ignored properties after the first occurrence of \u2018{0}\u2019.
 IgnoredPropertyAssociatedTo_1   = Ignored property associated to \u2018{0}\u2019.
+IncompleteFormattingOrParsing_2 = {0,choice,0#Formatting|1#Parsing} of \u201c{1}\u201d done, but some elements were ignored.
 LocalesDiscarded                = Text were discarded for some locales.
 OptionalModuleNotFound_1        = Optional module \u201c{0}\u201d requested but not found.
 PropertyHiddenBy_2              = Property \u201c{0}\u201d is hidden by \u201c{1}\u201d.
 MismatchedEllipsoidAxisLength_3 = The \u201c{1}\u201d parameter could have been omitted. But it has been given a value of {2} which does not match the definition of the \u201c{0}\u201d ellipsoid.
 NotFormalProjectionParameter_1  = This parameter borrowed from the \u201c{0}\u201d projection is not formally a parameter of this projection.
+UnknownElementsInText           = The text contains unknown elements:
 UnparsableValueStoredAsText_2   = Can not parse \u201c{1}\u201d as an instance of \u2018{0}\u2019. The value is stored as plain text instead, but will be ignored by some processing.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] Thu Jun 18 17:38:16 2015
@@ -14,6 +14,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+#
+# Punctuation rules in French (source: http://unicode.org/udhr/n/notes_fra.html)
+#
+#   U+202F NARROW NO-BREAK SPACE  before  ; ! and ?
+#   U+00A0 NO-BREAK SPACE         before  :
+#
 AlreadyRegistered_2             = Le {0} \u00ab\u202f{1}\u202f\u00bb est d\u00e9j\u00e0 inscrit dans le registre. La seconde instance sera ignor\u00e9e.
 ChangedContainerCapacity_2      = Changement de la capacit\u00e9 du conteneur de {0} vers {1} \u00e9l\u00e9ments.
 ConformanceMeansDatumShift      = Ce r\u00e9sultat indique si un changement de r\u00e9f\u00e9rentiel a \u00e9t\u00e9 appliqu\u00e9.
@@ -21,9 +28,11 @@ ConstantProjParameterValue_1    = Ce par
 DiscardedExclusiveProperty_2    = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 \u00e9cart\u00e9e en faveur de \u00ab\u202f{1}\u202f\u00bb, parce que ces deux propri\u00e9t\u00e9s sont mutuellement exclusives.
 IgnoredPropertiesAfterFirst_1   = Des propri\u00e9t\u00e9s ont \u00e9t\u00e9 ignor\u00e9es apr\u00e8s la premi\u00e8re occurrence de \u2018{0}\u2019.
 IgnoredPropertyAssociatedTo_1   = Une propri\u00e9t\u00e9 associ\u00e9e \u00e0 \u2018{0}\u2019 a \u00e9t\u00e9 ignor\u00e9e.
+IncompleteFormattingOrParsing_2 = {0,choice,0#L\u2019\u00e9criture|1#La lecture} de \u00ab\u202f{1}\u202f\u00bb a \u00e9t\u00e9 faite, mais en ignorant certains \u00e9l\u00e9ments.
 LocalesDiscarded                = Des textes ont \u00e9t\u00e9 ignor\u00e9s pour certaines langues.
 OptionalModuleNotFound_1        = Le module optionnel \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 demand\u00e9 mais n\u2019a pas \u00e9t\u00e9 trouv\u00e9.
 PropertyHiddenBy_2              = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb est masqu\u00e9e par \u00ab\u202f{1}\u202f\u00bb.
 MismatchedEllipsoidAxisLength_3 = Le param\u00e8tre \u00ab\u202f{1}\u202f\u00bb aurait pu \u00eatre omis. Mais il lui a \u00e9t\u00e9 donn\u00e9 la valeur {2} qui ne correspond pas \u00e0 la d\u00e9finition de l\u2019ellipso\u00efde \u00ab\u202f{0}\u202f\u00bb.
 NotFormalProjectionParameter_1  = Ce param\u00e8tre emprunt\u00e9 \u00e0 la projection \u00ab\u202f{0}\u202f\u00bb n\u2019est pas formellement un param\u00e8tre de cette projection.
+UnknownElementsInText           = Le texte contient des \u00e9l\u00e9ments inconnus\u00a0:
 UnparsableValueStoredAsText_2   = La valeur \u00ab\u202f{1}\u202f\u00bb ne peut pas \u00eatre interpr\u00e9t\u00e9e comme une instance de \u2018{0}\u2019. Elle est donc m\u00e9moris\u00e9e sous sa forme textuelle, mais sera ignor\u00e9e par certains traitements.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1686282&r1=1686281&r2=1686282&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Thu Jun 18 17:38:16 2015
@@ -211,6 +211,11 @@ public final class Vocabulary extends In
         public static final short Implementation = 21;
 
         /**
+         *  in 
+         */
+        public static final short InBetweenWords = 87;
+
+        /**
          * Index
          */
         public static final short Index = 22;
@@ -351,6 +356,11 @@ public final class Vocabulary extends In
         public static final short Paths = 46;
 
         /**
+         * “{0}”
+         */
+        public static final short Quoted_1 = 86;
+
+        /**
          * Root
          */
         public static final short Root = 47;



Mime
View raw message