sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1732673 - in /sis/branches/JDK8: application/sis-console/src/main/java/org/apache/sis/console/ application/sis-console/src/main/resources/org/apache/sis/console/ core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/ core/sis...
Date Sat, 27 Feb 2016 22:08:42 GMT
Author: desruisseaux
Date: Sat Feb 27 22:08:41 2016
New Revision: 1732673

URL: http://svn.apache.org/viewvc?rev=1732673&view=rev
Log:
Complete the support of the "identifier" command on the command-line tools.
This work includes a bug fix in comparison of ProjectedCRS with ComparisonMode.ALLOWS_VARIANT
and more extensive test in ConsistencyTest.

Added:
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java
      - copied, changed from r1732567, sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
    sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties   (with props)
    sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties   (with props)
    sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties   (with props)
Modified:
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties

Copied: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java (from r1732567, sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java?p2=sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java&p1=sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java&r1=1732567&r2=1732673&rev=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierRow.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -16,321 +16,172 @@
  */
 package org.apache.sis.console;
 
+import java.util.Set;
 import java.util.EnumSet;
-import java.io.Console;
-import java.io.IOException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.JAXBException;
-import org.opengis.metadata.Metadata;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.io.PrintWriter;
 import org.opengis.metadata.Identifier;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.ReferenceSystem;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.io.TableAppender;
-import org.apache.sis.io.wkt.WKTFormat;
-import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.io.wkt.Colors;
-import org.apache.sis.metadata.MetadataStandard;
-import org.apache.sis.metadata.ValueExistencePolicy;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.CRS;
-import org.apache.sis.storage.DataStore;
-import org.apache.sis.storage.DataStores;
-import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.internal.util.X364;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Utilities;
-import org.apache.sis.util.collection.TableColumn;
-import org.apache.sis.util.collection.TreeTable;
-import org.apache.sis.util.collection.TreeTableFormat;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.xml.MarshallerPool;
-import org.apache.sis.xml.XML;
+import org.apache.sis.util.resources.Vocabulary;
 
 
 /**
- * The "metadata", "crs" and "identifier" subcommands.
- * CRS are considered as a kind of metadata here.
+ * A row containing a metadata or CRS identifier, its name and a status flag.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.3
+ * @since   0.7
  * @version 0.7
  * @module
  */
-final class MetadataSC extends SubCommand {
+final class IdentifierRow {
     /**
-     * The desired information.
+     * The state to write in the left margin before the identifier.
+     *
+     * <b>MAINTENANCE NOTE:</b> if this enumeration is modified,
+     * update {@code IdentifierState.properties} accordingly.
      */
-    static enum Info {
-        METADATA, CRS, IDENTIFIER
-    }
+    static enum State {
+        VALID("   "), APPROXIMATIVE("~  "), AXIS_ORDER("!  "), MISMATCH("!! "), UNKNOWN("?  ");
 
-    /**
-     * The output format.
-     */
-    private static enum Format {
-        TEXT, WKT, XML
+        /** The string representation. */ final String text;
+        private State(final String p) {this.text = p;};
     }
 
     /**
-     * The sub-command: {@code "metadata"}, {@code "crs"} or {@code "identifier"}.
-     */
-    private final Info command;
-
-    /**
-     * The output format.
+     * The two-letters state to write before the identifier.
      */
-    private Format outputFormat;
+    private final State state;
 
     /**
-     * The WKT convention, or {@code null} if it does not apply.
+     * The identifier.
      */
-    private Convention convention;
+    private final String identifier;
 
     /**
-     * Creates the {@code "metadata"}, {@code "crs"} or {@code "identifier"} sub-command.
+     * A description to write after the identifier.
      */
-    MetadataSC(final Info command, final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.FORMAT, Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
-                Option.COLORS, Option.HELP, Option.DEBUG));
-        this.command = command;
-    }
+    private final CharSequence description;
 
     /**
-     * Parses the command-line arguments and initializes the {@link #outputFormat} and {@link #convention} fields
-     * accordingly. This method verifies the parameter validity.
+     * Creates a row for the given elements.
      */
-    private void parseArguments() throws InvalidOptionException {
-        /*
-         * Output format can be either "text" (the default) or "xml".
-         * In the case of "crs" sub-command, we accept also WKT variants.
-         */
-        final String format = options.get(Option.FORMAT);
-        if (format == null || format.equalsIgnoreCase("text")) {
-            if (command == Info.CRS) {
-                outputFormat = Format.WKT;
-                convention = Convention.WKT2_SIMPLIFIED;
-            } else {
-                outputFormat = Format.TEXT;
-            }
-        } else if (format.equalsIgnoreCase("wkt") || format.equalsIgnoreCase("wkt2")) {
-            outputFormat = Format.WKT;
-            convention = Convention.WKT2;
-        } else if (format.equalsIgnoreCase("wkt1")) {
-            outputFormat = Format.WKT;
-            convention = Convention.WKT1;
-        } else if (format.equalsIgnoreCase("xml")) {
-            outputFormat = Format.XML;
-        } else {
-            throw new InvalidOptionException(Errors.format(
-                    Errors.Keys.IllegalOptionValue_2, "format", format), format);
-        }
-        final boolean isFormatCompatible;
-        switch (command) {
-            case CRS: {
-                isFormatCompatible = true;
-                break;
-            }
-            case IDENTIFIER: {
-                isFormatCompatible = (outputFormat == Format.TEXT);
-                break;
-            }
-            default: {
-                isFormatCompatible = (convention == null);
-                break;
-            }
-        }
-        if (!isFormatCompatible) {
-            throw new InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2,
-                    command.name().toLowerCase(locale), format), format);
-        }
+    IdentifierRow(final State state, final String identifier, final CharSequence description) {
+        this.state       = state;
+        this.identifier  = identifier;
+        this.description = description;
     }
 
     /**
-     * Prints metadata or CRS information.
+     * Creates an identifier row for the given CRS.
+     * This method gives precedence to {@code "urn:ogc:def:"} identifiers if possible.
      *
-     * @throws DataStoreException if an error occurred while reading the file.
-     * @throws JAXBException if an error occurred while producing the XML output.
-     * @throws FactoryException if an error occurred while looking for a CRS identifier.
-     * @throws IOException should never happen, since we are appending to a print writer.
+     * @return The row, or {@code null} if no identifier has been found.
      */
-    @Override
-    @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    public int run() throws InvalidOptionException, DataStoreException, JAXBException, FactoryException, IOException {
-        parseArguments();
-        /*
-         * Read metadata from the data storage only aftr we verified that the arguments are valid.
-         * The input can be a file given on the command line, or the standard input stream.
-         */
-        final Metadata metadata;
-        if (useStandardInput()) {
-            try (DataStore store = DataStores.open(System.in)) {
-                metadata = store.getMetadata();
-            }
-        } else {
-            if (hasUnexpectedFileCount(1, 1)) {
-                return Command.INVALID_ARGUMENT_EXIT_CODE;
-            }
-            try (DataStore store = DataStores.open(files.get(0))) {
-                metadata = store.getMetadata();
-            }
-        }
-        if (metadata == null) {
-            return 0;
-        }
-        /*
-         * If we are executing the "identifier" sub-command, then show the metadata identifier (if any)
-         * and the identifier of all referencing systems found. Otherwise if we are executing the "crs"
-         * sub-command, extract only the first CRS. That CRS will be displayed after the switch statement.
-         */
-        Object object = metadata;
-choice: switch (command) {
-            case IDENTIFIER: {
-                final TableAppender table = new TableAppender(out, "    ");
-                appendIdentifier(table, metadata);
-                for (final ReferenceSystem rs : metadata.getReferenceSystemInfo()) {
-                    appendIdentifier(table, rs);
+    static IdentifierRow create(ReferenceSystem rs) throws FactoryException {
+        String identifier = IdentifiedObjects.lookupURN(rs, null);
+        if (identifier == null) {
+            /*
+             * If we can not find an identifier matching the EPSG or WMS definitions,
+             * look at the identifiers declared in the CRS and verify their validity.
+             */
+            for (final Identifier id : rs.getIdentifiers()) {
+                final String c = IdentifiedObjects.toURN(rs.getClass(), id);
+                if (c != null) {
+                    identifier = c;
+                    break;                                          // Stop at the first "urn:ogc:def:…".
                 }
-                table.flush();
-                return 0;
-            }
-            case CRS: {
-                for (final ReferenceSystem rs : metadata.getReferenceSystemInfo()) {
-                    if (rs instanceof CoordinateReferenceSystem) {
-                        object = rs;
-                        break choice;
-                    }
+                if (identifier == null) {
+                    identifier = IdentifiedObjects.toString(id);    // "AUTHORITY:CODE" as a fallback if no URN.
                 }
-                return 0;
+            }
+            if (identifier == null) {
+                return null;                                        // No identifier found.
             }
         }
         /*
-         * Format metadata to the standard output stream.
+         * The CRS provided by the user contains identifier, but the 'lookupURN' operation above failed to
+         * find it. The most likely cause is that the user-provided CRS does not use the same axis order.
          */
-        switch (outputFormat) {
-            case TEXT: {
-                final TreeTable tree = MetadataStandard.ISO_19115.asTreeTable(object, ValueExistencePolicy.NON_EMPTY);
-                final TreeTableFormat tf = new TreeTableFormat(locale, timezone);
-                tf.setColumns(TableColumn.NAME, TableColumn.VALUE);
-                tf.format(tree, out);
-                break;
-            }
-
-            case WKT: {
-                final WKTFormat f = new WKTFormat(locale, timezone);
-                if (convention != null) {
-                    f.setConvention(convention);
+        State state;
+        try {
+            final ReferenceSystem def = CRS.forCode(identifier);
+            final ComparisonMode c = ComparisonMode.equalityLevel(def, rs);
+            if (c == null) {
+                state = State.MISMATCH;
+            } else switch (c) {
+                case ALLOW_VARIANT: {
+                    state = State.AXIS_ORDER;
+                    break;
                 }
-                if (colors) {
-                    f.setColors(Colors.DEFAULT);
+                case APPROXIMATIVE: {
+                    state = State.APPROXIMATIVE;
+                    rs = def;
+                    break;
                 }
-                f.format(object, out);
-                out.println();
-                break;
-            }
-
-            case XML: {
-                final MarshallerPool pool = new MarshallerPool(null);
-                final Marshaller marshaller = pool.acquireMarshaller();
-                marshaller.setProperty(XML.LOCALE,   locale);
-                marshaller.setProperty(XML.TIMEZONE, timezone);
-                if (isConsole()) {
-                    marshaller.marshal(object, out);
-                } else {
-                    out.flush();
-                    marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding.name());
-                    marshaller.marshal(object, System.out);     // Intentionally use OutputStream instead than Writer.
-                    System.out.flush();
+                default: {
+                    state = State.VALID;
+                    rs = def;
+                    break;
                 }
-                break;
             }
+        } catch (NoSuchAuthorityCodeException e) {
+            state = State.UNKNOWN;
         }
-        out.flush();
-        return 0;
-    }
-
-    /**
-     * Returns {@code true} if {@link #out} is sending its output to the console.
-     * If not, then we are probably writing to a file or the user specified his own encoding.
-     * In such case, we will send the XML output to an {@code OutputStream} instead than to a
-     * {@code Writer} and let the marshaller apply the encoding itself.
-     */
-    private boolean isConsole() {
-        if (outputBuffer != null) return true;                      // Special case for JUnit tests only.
-        final Console console = System.console();
-        return (console != null) && console.writer() == out;
+        return new IdentifierRow(state, identifier, rs.getName().getCode());
     }
 
     /**
-     * Append a row to the given table provided that the identifier is non-null.
-     * If the given identifier is {@code null}, then this method does nothing.
+     * Prints all non-null rows to the given output.
      */
-    private static void appendRow(final TableAppender table, final CharSequence identifier,
-            final char separator, final CharSequence legend)
+    static void print(final Iterable<IdentifierRow> rows, final PrintWriter out,
+            final Locale locale, final boolean colors)
     {
-        if (identifier != null) {
-            table.append(identifier).nextColumn();
-            if (legend != null) {
-                table.append(separator).append(' ').append(legend);
+        int width = 0;
+        for (final IdentifierRow row : rows) {
+            if (row != null) {
+                width = Math.max(width, row.identifier.length());
+            }
+        }
+        width += 4;
+        final Set<State> states = EnumSet.noneOf(State.class);
+        for (final IdentifierRow row : rows) {
+            if (row != null) {
+                states.add(row.state);
+                final boolean warning = colors && row.state.text.startsWith("!");
+                if (warning) out.print(X364.FOREGROUND_RED.sequence());
+                out.print(row.state.text);
+                out.print(' ');
+                out.print(row.identifier);
+                if (warning) out.print(X364.FOREGROUND_DEFAULT.sequence());
+                if (colors)  out.print(X364.FOREGROUND_GRAY.sequence());
+                out.print(CharSequences.spaces(width - row.identifier.length()));
+                out.print("| ");
+                out.println(row.description);
+                if (colors) out.print(X364.FOREGROUND_DEFAULT.sequence());
+            }
+        }
+        states.remove(State.VALID);
+        if (!states.isEmpty()) {
+            out.println();
+            out.println(Vocabulary.getResources(locale).getLabel(Vocabulary.Keys.Legend));
+            final ResourceBundle resources = ResourceBundle.getBundle("org.apache.sis.console.IdentifierState", locale);
+            for (final State state : states) {
+                final boolean warning = colors && state.text.startsWith("!");
+                if (warning) out.print(X364.FOREGROUND_RED.sequence());
+                out.print(state.text);
+                if (warning) out.print(X364.FOREGROUND_DEFAULT.sequence());
+                out.print(' ');
+                out.println(resources.getString(state.name()));
             }
-            table.nextLine();
         }
-    }
-
-    /**
-     * Appends the metadata identifier to the given table.
-     */
-    private void appendIdentifier(final TableAppender table, final Metadata metadata) {
-        final Identifier id = metadata.getMetadataIdentifier();
-        if (id != null) {
-            CharSequence desc = id.getDescription();
-            if (desc != null && !files.isEmpty()) desc = files.get(0);
-            appendRow(table, IdentifiedObjects.toString(id), '-', desc);
-        }
-    }
-
-    /**
-     * Append the CRS identifier to the given table.
-     * This method gives precedence to {@code "urn:ogc:def:"} identifiers if possible.
-     */
-    private static void appendIdentifier(final TableAppender table, final ReferenceSystem rs) throws FactoryException {
-        char separator;
-        String legend;
-        String identifier = IdentifiedObjects.lookupURN(rs, null);
-        if (identifier != null) {
-            separator = '-';
-            legend = rs.getName().getCode();
-        } else {
-            for (final Identifier id : rs.getIdentifiers()) {
-                final String c = IdentifiedObjects.toURN(rs.getClass(), id);
-                if (c != null) {
-                    identifier = c;
-                    break;                                          // Stop at the first "urn:ogc:def:…".
-                }
-                if (identifier == null) {
-                    identifier = IdentifiedObjects.toString(id);    // "AUTHORITY:CODE" as a fallback if no URN.
-                }
-            }
-            if (identifier == null) {
-                return;                                             // No identifier found.
-            }
-            /*
-             * The CRS provided by the user contains identifier, but the 'lookupURN' operation above failed to
-             * find it. The most likely cause is that the user-provided CRS does not use the same axis order.
-             */
-            try {
-                separator = '!';
-                final ReferenceSystem def = CRS.forCode(identifier);
-                if (Utilities.deepEquals(def, rs, ComparisonMode.ALLOW_VARIANT)) {
-                    legend = "Axis order does not match the definition.";
-                } else {
-                    legend = "Apparently wrong identifier!";
-                }
-            } catch (NoSuchAuthorityCodeException e) {
-                separator = '?';
-                legend = "Exactness of this identifier has not been verified.";
-            }
-        }
-        appendRow(table, identifier, separator, legend);
+        out.flush();
     }
 }

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.console;
 
+import java.util.List;
+import java.util.ArrayList;
 import java.util.EnumSet;
 import java.io.Console;
 import java.io.IOException;
@@ -24,22 +26,17 @@ import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.Identifier;
 import org.opengis.util.FactoryException;
-import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Colors;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.ValueExistencePolicy;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.referencing.CRS;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStores;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Utilities;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTableFormat;
@@ -186,12 +183,17 @@ final class MetadataSC extends SubComman
         Object object = metadata;
 choice: switch (command) {
             case IDENTIFIER: {
-                final TableAppender table = new TableAppender(out, "    ");
-                appendIdentifier(table, metadata);
+                final List<IdentifierRow> rows = new ArrayList<>();
+                final Identifier id = metadata.getMetadataIdentifier();
+                if (id != null) {
+                    CharSequence desc = id.getDescription();
+                    if (desc != null && !files.isEmpty()) desc = files.get(0);
+                    rows.add(new IdentifierRow(IdentifierRow.State.VALID, IdentifiedObjects.toString(id), desc));
+                }
                 for (final ReferenceSystem rs : metadata.getReferenceSystemInfo()) {
-                    appendIdentifier(table, rs);
+                    rows.add(IdentifierRow.create(rs));
                 }
-                table.flush();
+                IdentifierRow.print(rows, out, locale, colors);
                 return 0;
             }
             case CRS: {
@@ -260,77 +262,4 @@ choice: switch (command) {
         final Console console = System.console();
         return (console != null) && console.writer() == out;
     }
-
-    /**
-     * Append a row to the given table provided that the identifier is non-null.
-     * If the given identifier is {@code null}, then this method does nothing.
-     */
-    private static void appendRow(final TableAppender table, final CharSequence identifier,
-            final char separator, final CharSequence legend)
-    {
-        if (identifier != null) {
-            table.append(identifier).nextColumn();
-            if (legend != null) {
-                table.append(separator).append(' ').append(legend);
-            }
-            table.nextLine();
-        }
-    }
-
-    /**
-     * Appends the metadata identifier to the given table.
-     */
-    private void appendIdentifier(final TableAppender table, final Metadata metadata) {
-        final Identifier id = metadata.getMetadataIdentifier();
-        if (id != null) {
-            CharSequence desc = id.getDescription();
-            if (desc != null && !files.isEmpty()) desc = files.get(0);
-            appendRow(table, IdentifiedObjects.toString(id), '-', desc);
-        }
-    }
-
-    /**
-     * Append the CRS identifier to the given table.
-     * This method gives precedence to {@code "urn:ogc:def:"} identifiers if possible.
-     */
-    private static void appendIdentifier(final TableAppender table, final ReferenceSystem rs) throws FactoryException {
-        char separator;
-        String legend;
-        String identifier = IdentifiedObjects.lookupURN(rs, null);
-        if (identifier != null) {
-            separator = '-';
-            legend = rs.getName().getCode();
-        } else {
-            for (final Identifier id : rs.getIdentifiers()) {
-                final String c = IdentifiedObjects.toURN(rs.getClass(), id);
-                if (c != null) {
-                    identifier = c;
-                    break;                                          // Stop at the first "urn:ogc:def:…".
-                }
-                if (identifier == null) {
-                    identifier = IdentifiedObjects.toString(id);    // "AUTHORITY:CODE" as a fallback if no URN.
-                }
-            }
-            if (identifier == null) {
-                return;                                             // No identifier found.
-            }
-            /*
-             * The CRS provided by the user contains identifier, but the 'lookupURN' operation above failed to
-             * find it. The most likely cause is that the user-provided CRS does not use the same axis order.
-             */
-            try {
-                separator = '!';
-                final ReferenceSystem def = CRS.forCode(identifier);
-                if (Utilities.deepEquals(def, rs, ComparisonMode.ALLOW_VARIANT)) {
-                    legend = "Axis order does not match the definition.";
-                } else {
-                    legend = "Apparently wrong identifier!";
-                }
-            } catch (NoSuchAuthorityCodeException e) {
-                separator = '?';
-                legend = "Exactness of this identifier has not been verified.";
-            }
-        }
-        appendRow(table, identifier, separator, legend);
-    }
 }

Added: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties?rev=1732673&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties (added)
+++ sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties [ISO-8859-1] Sat Feb 27 22:08:41 2016
@@ -0,0 +1,5 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
+APPROXIMATIVE=Identified object has minor numerical differences compared to definition provided by authority.
+AXIS_ORDER=Identified object matches definition provided by authority except for coordinate system axes.
+MISMATCH=Identifier associated to an object that does not match the definition provided by authority.
+UNKNOWN=Unknown identifier. Exactness can not be verified.

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=ISO-8859-1

Added: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties?rev=1732673&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties (added)
+++ sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties [ISO-8859-1] Sat Feb 27 22:08:41 2016
@@ -0,0 +1 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_en.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=ISO-8859-1

Added: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties?rev=1732673&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties (added)
+++ sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties [ISO-8859-1] Sat Feb 27 22:08:41 2016
@@ -0,0 +1,5 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
+APPROXIMATIVE=L\u2019objet identifié contient des différences numériques mineures comparativement à la définition fournie par l\u2019autorité.
+AXIS_ORDER=L\u2019objet identifié correspond à la définition fournie par l\u2019autorité, excepté les axes du système de coordonnées.
+MISMATCH=L\u2019identifiant est associé à un objet qui ne correspond pas à la définition fournie par l\u2019autorité.
+UNKNOWN=Identifiant inconnu. Son exactitude ne peut pas être vérifiée.

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/resources/org/apache/sis/console/IdentifierState_fr.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=ISO-8859-1

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -238,6 +238,12 @@ public class DefaultVerticalDatum extend
     /**
      * Returns the type of this vertical datum.
      *
+     * <div class="note"><b>Historical note:</b>
+     * this property was defined in the ISO 19111 specification published in 2003,
+     * but removed from the revision published 2007.
+     * This property provides an information similar to the {@linkplain #getAnchorPoint() anchor definition},
+     * but in a programmatic way more suitable to coordinate transformation engines.</div>
+     *
      * @return The type of this vertical datum.
      */
     @Override
@@ -257,7 +263,7 @@ public class DefaultVerticalDatum extend
     @Override
     public boolean equals(final Object object, final ComparisonMode mode) {
         if (object == this) {
-            return true; // Slight optimization.
+            return true;                                                    // Slight optimization.
         }
         if (!super.equals(object, mode)) {
             return false;
@@ -266,9 +272,18 @@ public class DefaultVerticalDatum extend
             case STRICT: {
                 return type().equals(((DefaultVerticalDatum) object).type());
             }
-            default: {
+            case BY_CONTRACT: {
                 return Objects.equals(getVerticalDatumType(), ((VerticalDatum) object).getVerticalDatumType());
             }
+            default: {
+                /*
+                 * VerticalDatumType is considered as metadata because it is related to the anchor definition,
+                 * which is itself considered as metadata. Furthermore GeodeticObjectParser and EPSGDataAccess
+                 * do not always set this property to the same value: the former uses the information provided
+                 * by the coordinate system axis while the other does not.
+                 */
+                return true;
+            }
         }
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -1556,9 +1556,6 @@ addURIs:    for (int i=0; ; i++) {
      * @return The datum for the given code.
      * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
      * @throws FactoryException if the object creation failed for some other reason.
-     *
-     * @todo Current implementation maps all "vertical" datum to {@link VerticalDatumType#GEOIDAL}.
-     *       We do not know yet how to maps the exact vertical datum type from the EPSG database.
      */
     @Override
     public synchronized Datum createDatum(final String code) throws NoSuchAuthorityCodeException, FactoryException {
@@ -1626,7 +1623,10 @@ addURIs:    for (int i=0; ; i++) {
                         break;
                     }
                     /*
-                     * Vertical datum type is hard-coded to geoidal for now. See @todo in method javadoc.
+                     * Vertical datum type is hard-coded to geoidal. It would be possible to infer other
+                     * types by looking at the coordinate system, but it could result in different datum
+                     * associated to the same EPSG code.  Since vertical datum type is no longer part of
+                     * ISO 19111:2007, it is probably not worth to handle such cases.
                      */
                     case "vertical": {
                         datum = datumFactory.createVerticalDatum(properties, VerticalDatumType.GEOIDAL);
@@ -3273,7 +3273,7 @@ next:               while (r.next()) {
                 return iteration != 0;
             }
         }
-        while (++iteration < 15);      // Arbitrary limit for avoiding never-ending loop.
+        while (++iteration < Formulas.MAXIMUM_ITERATIONS);      // Arbitrary limit for avoiding never-ending loop.
         return true;
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -798,10 +798,13 @@ check:      for (int isTarget=0; ; isTar
                         MathTransform tr1 = this.getMathTransform();
                         MathTransform tr2 = that.getMathTransform();
                         if (mode == ComparisonMode.ALLOW_VARIANT) try {
-                            final MathTransform swap = MathTransforms.linear(
+                            final MathTransform before = MathTransforms.linear(
                                     CoordinateSystems.swapAndScaleAxes(crs1.getCoordinateSystem(),
                                                                        crs2.getCoordinateSystem()));
-                            tr2 = MathTransforms.concatenate(swap, tr2);
+                            final MathTransform after = MathTransforms.linear(
+                                    CoordinateSystems.swapAndScaleAxes(that.getTargetCRS().getCoordinateSystem(),
+                                                                       this.getTargetCRS().getCoordinateSystem()));
+                            tr2 = MathTransforms.concatenate(before, tr2, after);
                         } catch (ConversionException | RuntimeException e) {
                             Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
                                     AbstractCoordinateOperation.class, "equals", e);

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -278,7 +278,7 @@ class ConcatenatedTransform extends Abst
             if (matrix2 != null) {
                 final Matrix matrix = Matrices.multiply(matrix2, matrix1);
                 if (Matrices.isIdentity(matrix, IDENTITY_TOLERANCE)) {
-                    return MathTransforms.identity(matrix.getNumRow() - 1);     // Returns a cached instance.
+                    return MathTransforms.identity(matrix.getNumRow() - 1);         // Returns a cached instance.
                 }
                 /*
                  * NOTE: It is quite tempting to "fix rounding errors" in the matrix before to create the transform.
@@ -322,7 +322,7 @@ class ConcatenatedTransform extends Abst
         if (areInverse(tr1, tr2) || areInverse(tr2, tr1)) {
             assert tr1.getSourceDimensions() == tr2.getTargetDimensions();
             assert tr1.getTargetDimensions() == tr2.getSourceDimensions();
-            return MathTransforms.identity(tr1.getSourceDimensions());      // Returns a cached instance.
+            return MathTransforms.identity(tr1.getSourceDimensions());          // Returns a cached instance.
         }
         /*
          * Gives a chance to AbstractMathTransform to returns an optimized object.
@@ -921,7 +921,7 @@ class ConcatenatedTransform extends Abst
      */
     @Override
     public boolean equals(final Object object, final ComparisonMode mode) {
-        if (object == this) { // Slight optimization
+        if (object == this) {                                                   // Slight optimization
             return true;
         }
         /*

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -17,20 +17,25 @@
 package org.apache.sis.test.integration;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.text.ParseException;
+import org.opengis.metadata.Identifier;
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.referencing.factory.FactoryDataException;
+import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Warnings;
 import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.wkt.UnformattableObjectException;
+import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.Utilities;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -63,6 +68,15 @@ public final strictfp class ConsistencyT
     ));
 
     /**
+     * Codes to exclude from the {@link #lookup(CoordinateReferenceSystem, CoordinateReferenceSystem)} test.
+     * The reason why those tests are excluded now is related to the way JSR-275 parse units. We may resolve
+     * those issues when we will replace JSR-275 by another library.
+     */
+    private static final Set<String> LOOKUP_EXCLUDES = Collections.singleton(
+            "EPSG:5754"         // Poolbeg height. Uses British foot (1936).
+    );
+
+    /**
      * Verifies the WKT consistency of all CRS instances.
      *
      * @throws FactoryException if an error other than "unsupported operation method" occurred.
@@ -87,8 +101,8 @@ public final strictfp class ConsistencyT
                     print(code, "WARNING", e.getLocalizedMessage());
                     continue;
                 }
-                parseAndFormat(v2,  code, crs);
-                parseAndFormat(v2s, code, crs);
+                lookup(parseAndFormat(v2,  code, crs), crs);
+                lookup(parseAndFormat(v2s, code, crs), crs);
                 /*
                  * There is more information lost in WKT 1 than in WKT 2, so we can not test everything.
                  * For example we can not format fully three-dimensional geographic CRS because the unit
@@ -118,14 +132,17 @@ public final strictfp class ConsistencyT
     }
 
     /**
-     * Format the given CRS using the given formatter, parses it and reformat again.
+     * Formats the given CRS using the given formatter, parses it and reformat again.
      * Then the two WKT are compared.
      *
-     * @param f    The formatter to use.
-     * @param code The authority code, used only in case of errors.
-     * @param crs  The CRS to test.
+     * @param  f    The formatter to use.
+     * @param  code The authority code, used only in case of errors.
+     * @param  crs  The CRS to test.
+     * @return The parsed CRS.
      */
-    private static void parseAndFormat(final WKTFormat f, final String code, final CoordinateReferenceSystem crs) {
+    private static CoordinateReferenceSystem parseAndFormat(final WKTFormat f,
+            final String code, final CoordinateReferenceSystem crs)
+    {
         String wkt = f.format(crs);
         final Warnings warnings = f.getWarnings();
         if (warnings != null && !warnings.getExceptions().isEmpty()) {
@@ -140,7 +157,7 @@ public final strictfp class ConsistencyT
             out.println();
             e.printStackTrace(out);
             fail(e.getLocalizedMessage());
-            return;
+            return null;
         }
         final String again = f.format(parsed);
         final CharSequence[] expectedLines = CharSequences.splitOnEOL(wkt);
@@ -200,5 +217,30 @@ public final strictfp class ConsistencyT
             throw e;
         }
         assertEquals("Unexpected number of lines.", expectedLines.length, actualLines.length);
+        return parsed;
+    }
+
+    /**
+     * Verifies that {@code IdentifiedObjects.lookupURN(…)} on the parsed CRS can find back the original CRS.
+     */
+    private static void lookup(final CoordinateReferenceSystem parsed, final CoordinateReferenceSystem crs)
+            throws FactoryException
+    {
+        final Identifier id = IdentifiedObjects.getIdentifier(crs, null);
+        if (LOOKUP_EXCLUDES.contains(IdentifiedObjects.toString(id))) {
+            return;
+        }
+        /*
+         * Lookup operation is not going to work if the CRS are not approximatively equal.
+         */
+        final String urn = IdentifiedObjects.toURN(crs.getClass(), id);
+        assertNotNull(crs.getName().getCode(), urn);
+        assertTrue(urn, Utilities.deepEquals(crs, parsed, ComparisonMode.DEBUG));
+        /*
+         * Now test the lookup operation. Since the parsed CRS has an identifier,
+         * that lookup operation should not do a lot of work actually.
+         */
+        final String lookup = IdentifiedObjects.lookupURN(parsed, null);
+        assertEquals("Failed to lookup the parsed CRS.", urn, lookup);
     }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -84,10 +84,13 @@ public final class Numerics extends Stat
      *
      * By extension, the same threshold value is used for comparing other floating point values.
      *
+     * <p>The current value is set to the smallest power of 10 which allow the
+     * {@code org.apache.sis.test.integration.ConsistencyTest} to pass.</p>
+     *
      * @see org.apache.sis.internal.referencing.Formulas#LINEAR_TOLERANCE
      * @see org.apache.sis.internal.referencing.Formulas#ANGULAR_TOLERANCE
      */
-    public static final double COMPARISON_THRESHOLD = 1E-14;
+    public static final double COMPARISON_THRESHOLD = 1E-13;
 
     /**
      * Bit mask to isolate the sign bit of non-{@linkplain Double#isNaN(double) NaN} values in a

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Sat Feb 27 22:08:41 2016
@@ -266,6 +266,11 @@ public final class Vocabulary extends In
         public static final short Latitude = 26;
 
         /**
+         * Legend
+         */
+        public static final short Legend = 97;
+
+        /**
          * Level
          */
         public static final short Level = 94;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Sat Feb 27 22:08:41 2016
@@ -57,6 +57,7 @@ JavaHome                = Java home dire
 Julian                  = Julian
 Latitude                = Latitude
 Longitude               = Longitude
+Legend                  = Legend
 Level                   = Level
 Libraries               = Libraries
 LocalConfiguration      = Local configuration

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1732673&r1=1732672&r2=1732673&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Sat Feb 27 22:08:41 2016
@@ -64,6 +64,7 @@ JavaHome                = R\u00e9pertoir
 Julian                  = Julien
 Latitude                = Latitude
 Longitude               = Longitude
+Legend                  = L\u00e9gende
 Level                   = Niveau
 Libraries               = Biblioth\u00e8ques
 LocalConfiguration      = Configuration locale



Mime
View raw message