sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1675957 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-metadata/src/test/java/org/apache/sis/io/wkt/ sis-metadata/src/test/java/org/apache/sis/test/mock/ sis-metadata/src/test/java/org/apache/sis/test/s...
Date Fri, 24 Apr 2015 21:27:49 GMT
Author: desruisseaux
Date: Fri Apr 24 21:27:48 2015
New Revision: 1675957

URL: http://svn.apache.org/r1675957
Log:
Referencing: better replacements of non-ASCII characters in WKT formatting, as required by ISO 19162.
The replacement of axis abbreviations can be controlled by users.

This is part of https://issues.apache.org/jira/browse/SIS-163

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java   (with props)
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java   (with props)
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java
      - copied, changed from r1675811, sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java

Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java?rev=1675957&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java (added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.io.wkt;
+
+import java.io.Serializable;
+import org.opengis.referencing.cs.PolarCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.apache.sis.util.CharSequences;
+
+
+/**
+ * Controls the replacement on Unicode characters during WKT formatting.
+ * The ISO 19162 standard restricts <cite>Well Known Text</cite> to the following characters in all
+ * {@linkplain Formatter#append(String, ElementKind) quoted texts} except in {@code REMARKS["…"]} elements:
+ *
+ * <blockquote><pre>{@literal A-Z a-z 0-9 _ [ ] ( ) { } < = > . , : ; + - (space) % & ' " * ^ / \ ? | °}</pre></blockquote>
+ *
+ * They are ASCII codes 32 to 125 inclusive except ! (33), # (35), $ (36), @ (64) and ` (96),
+ * plus the addition of ° (176) despite being formally outside the ASCII character set.
+ * The only exception to this rules is for the text inside {@code REMARKS["…"]} elements,
+ * where all Unicode characters are allowed.
+ *
+ * <div class="section">Application to mathematical symbols</div>
+ * For Greek letters used as mathematical symbols or
+ * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getAbbreviation() coordinate axis abbreviations},
+ * the ISO 19162 standard recommends:
+ *
+ * <ul>
+ *   <li>(<var>P</var>, <var>L</var>) as the transliteration of the Greek letters (<var>phi</var>, <var>lambda</var>), or
+ *       (<var>B</var>, <var>L</var>) from German “Breite” and “Länge” used in academic texts worldwide, or
+ *       (<var>lat</var>, <var>long</var>).</li>
+ *   <li>(<var>U</var>) for (θ) in {@linkplain org.apache.sis.referencing.cs.DefaultPolarCS polar coordinate systems}.</li>
+ *   <li>(<var>U</var>, <var>V</var>) for (φ, θ) in
+ *       {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical coordinate systems}.</li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+public abstract class CharEncoding implements Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 7115456393795045932L;
+
+    /**
+     * A character encoding compliant with ISO 19162 on a <cite>"best effort"</cite> basis.
+     * All methods perform the default implementation documented in this {@code CharEncoding} class.
+     */
+    public static final CharEncoding DEFAULT = new Default();
+
+    /**
+     * A character encoding that does not perform any replacement.
+     * All methods let Unicode characters pass-through unchanged.
+     */
+    public static final CharEncoding UNICODE = new Unicode();
+
+    /**
+     * For sub-class constructors.
+     */
+    protected CharEncoding() {
+    }
+
+    /**
+     * Returns a character sequences with the non-ASCII characters replaced or removed.
+     * The default implementation invokes {@link CharSequences#toASCII(CharSequence)}.
+     *
+     * <p>Implementations shall not care about {@linkplain Symbols#getOpeningQuote(int) opening} or
+     * {@linkplain Symbols#getClosingQuote(int) closing quotes}. The quotes will be doubled by the
+     * caller if needed.</p>
+     *
+     * @param  text The text to format without non-ASCII characters.
+     * @return The text to write in <cite>Well Known Text</cite>.
+     */
+    public String filter(final String text) {
+        return CharSequences.toASCII(text).toString();
+    }
+
+    /**
+     * Returns the axis abbreviation to format, or {@code null} if none. The abbreviation is obtained by
+     * {@link CoordinateSystemAxis#getAbbreviation()}, but may contain Greek letters (in particular φ, λ
+     * and θ).
+     *
+     * @param  cs   The enclosing coordinate system, or {@code null} if unknown.
+     * @param  axis The axis for which to get the abbreviation to format.
+     * @return The axis abbreviation to format.
+     *
+     * @see org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#formatTo(Formatter)
+     */
+    public String getAbbreviation(final CoordinateSystem cs, final CoordinateSystemAxis axis) {
+        String a = axis.getAbbreviation();
+        if (a != null && !a.isEmpty() && a.length() <= 2) {
+            switch (a.charAt(0)) {
+                /*
+                 * ISO 19162 §7.5.3 recommendations:
+                 *
+                 *   a) For PolarCS using Greek letter θ for direction, the letter ‘U’ should be used in WKT.
+                 *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
+                 */
+                case 'θ': {
+                    if  (cs instanceof SphericalCS) a ="V";
+                    else if (cs instanceof PolarCS) a ="U";
+                    break;
+                }
+                /*
+                 * ISO 19162 §7.5.3 requirement (ii) and recommendation (b):
+                 *
+                 *  ii) Greek letters φ and λ for geodetic latitude and longitude must be replaced by Latin char.
+                 *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
+                 *
+                 * Note that some SphericalCS may use φ′ or φc for distinguishing from geodetic latitude φ.
+                 */
+                case 'φ': {
+                    if (cs instanceof SphericalCS) {
+                        a = "U";
+                    } else if (cs instanceof EllipsoidalCS) {
+                        a = "B";    // From German "Breite", used in academic texts worldwide.
+                    }
+                    break;
+                }
+                case 'λ': {
+                    if (cs instanceof EllipsoidalCS) {
+                        a = "L";    // From German "Länge", used in academic texts worldwide.
+                    }
+                    break;
+                }
+            }
+        }
+        return a;
+    }
+
+    /**
+     * The {@link CharEncoding#DEFAULT} implementation.
+     */
+    private static final class Default extends CharEncoding {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = 4869597020294928525L;
+
+        /** Returns a string representation similar to enum. */
+        @Override public String toString() {
+            return "DEFAULT";
+        }
+
+        /** Replaces deserialized instances by the unique instance. */
+        Object readResolve() {
+            return DEFAULT;
+        }
+    }
+
+    /**
+     * The {@link CharEncoding#UNICODE} implementation.
+     */
+    private static final class Unicode extends CharEncoding {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = 7392131912748253956L;
+
+        /** Performs no replacement. */
+        @Override public String filter(String text) {
+            return text;
+        }
+
+        /** Returns the abbreviation as-is. */
+        @Override public String getAbbreviation(CoordinateSystem cs, CoordinateSystemAxis axis) {
+            return axis.getAbbreviation();
+        }
+
+        /** Returns a string representation similar to enum. */
+        @Override public String toString() {
+            return "UNICODE";
+        }
+
+        /** Replaces deserialized instances by the unique instance. */
+        Object readResolve() {
+            return UNICODE;
+        }
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/CharEncoding.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -168,10 +168,11 @@ public class Formatter implements Locali
     private Citation authority;
 
     /**
-     * {@code true} for preserving non-ASCII characters. The default value is {@code false},
-     * which causes replacements like "é" → "e" in all elements except {@code REMARKS["…"]}.
+     * {@link CharEncoding#UNICODE} for preserving non-ASCII characters. The default value is
+     * {@link CharEncoding#DEFAULT}, which causes replacements like "é" → "e" in all elements
+     * except {@code REMARKS["…"]}. May also be a user-supplied encoding.
      */
-    boolean isNonAsciiAllowed;
+    CharEncoding encoding;
 
     /**
      * The enclosing WKT element being formatted.
@@ -383,7 +384,7 @@ public class Formatter implements Locali
         this.colors       = colors;
         this.toUpperCase  = toUpperCase;
         this.indentation  = indentation;
-        isNonAsciiAllowed = (convention == Convention.INTERNAL);
+        this.encoding     = (convention == Convention.INTERNAL) ? CharEncoding.UNICODE : CharEncoding.DEFAULT;
     }
 
     /**
@@ -399,6 +400,28 @@ public class Formatter implements Locali
     }
 
     /**
+     * Returns a mapper between Java character sequences and the characters to write in WKT.
+     * The intend is to specify how to write characters that are not allowed in WKT strings
+     * according ISO 19162 specification. Return values can be:
+     *
+     * <ul>
+     *   <li>{@link CharEncoding#DEFAULT} for performing replacements like "é" → "e"
+     *       in all WKT elements except {@code REMARKS["…"]}.</li>
+     *   <li>{@link CharEncoding#UNICODE} for preserving non-ASCII characters.</li>
+     *   <li>Any other user-supplied mapping.</li>
+     * </ul>
+     *
+     * @return The mapper between Java character sequences and the characters to write in WKT.
+     *
+     * @see WKTFormat#setCharEncoding(CharEncoding)
+     *
+     * @since 0.6
+     */
+    public final CharEncoding getCharEncoding() {
+        return encoding;
+    }
+
+    /**
      * Returns the preferred authority for choosing the projection and parameter names.
      *
      * <p>The preferred authority can be set by the {@link WKTFormat#setNameAuthority(Citation)} method.
@@ -927,10 +950,10 @@ public class Formatter implements Locali
     private void quote(final String text, final ElementKind type) {
         setColor(type);
         final int base = buffer.appendCodePoint(symbols.getOpeningQuote(0)).length();
-        if (isNonAsciiAllowed || (type == ElementKind.REMARKS)) {
+        if (type == ElementKind.REMARKS) {
             buffer.append(text);
         } else {
-            buffer.append(CharSequences.toASCII(text));
+            buffer.append(encoding.filter(text));
         }
         closeQuote(base);
         resetColor();

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -41,10 +41,11 @@ import org.apache.sis.util.resources.Err
  * {@code WKTFormat} objects allow the following configuration:
  *
  * <ul>
- *   <li>The {@linkplain Symbols symbols} to use (curly braces or brackets, <i>etc</i>).</li>
  *   <li>The preferred authority of {@linkplain IdentifiedObject#getName() object name} to
  *       format (see {@link Formatter#getNameAuthority()} for more information).</li>
- *   <li>Whatever ANSI X3.64 colors are allowed or not (default is not).</li>
+ *   <li>The {@linkplain Symbols symbols} to use (curly braces or brackets, <i>etc</i>).</li>
+ *   <li>The {@linkplain CharEncoding character encoding} (i.e. replacements to use for Unicode characters).</li>
+ *   <li>Whether ANSI X3.64 colors are allowed or not (default is not).</li>
  *   <li>The indentation.</li>
  * </ul>
  *
@@ -78,7 +79,7 @@ import org.apache.sis.util.resources.Err
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Rémi Eve (IRD)
  * @since   0.4
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public class WKTFormat extends CompoundFormat<Object> {
@@ -146,10 +147,13 @@ public class WKTFormat extends CompoundF
     private KeywordCase keywordCase;
 
     /**
-     * {@code true} for preserving non-ASCII characters. The default value is {@code false},
-     * which causes replacements like "é" → "e" in all elements except {@code REMARKS["…"]}.
+     * {@link CharEncoding#UNICODE} for preserving non-ASCII characters. The default value is
+     * {@link CharEncoding#DEFAULT}, which causes replacements like "é" → "e" in all elements
+     * except {@code REMARKS["…"]}. May also be a user-supplied encoding.
+     *
+     * <p>A {@code null} value means to infer this property from the {@linkplain #convention}.</p>
      */
-    private boolean isNonAsciiAllowed;
+    private CharEncoding encoding;
 
     /**
      * The amount of spaces to use in indentation, or {@value #SINGLE_LINE} if indentation is disabled.
@@ -224,6 +228,45 @@ public class WKTFormat extends CompoundF
     }
 
     /**
+     * Returns a mapper between Java character sequences and the characters to write in WKT.
+     * The intend is to specify how to write characters that are not allowed in WKT strings
+     * according ISO 19162 specification. Return values can be:
+     *
+     * <ul>
+     *   <li>{@link CharEncoding#DEFAULT} for performing replacements like "é" → "e"
+     *       in all WKT elements except {@code REMARKS["…"]}.</li>
+     *   <li>{@link CharEncoding#UNICODE} for preserving non-ASCII characters.</li>
+     *   <li>Any other user-supplied mapping.</li>
+     * </ul>
+     *
+     * @return The mapper between Java character sequences and the characters to write in WKT.
+     *
+     * @since 0.6
+     */
+    public CharEncoding getCharEncoding() {
+        CharEncoding result = encoding;
+        if (result == null) {
+            result = (convention == Convention.INTERNAL) ? CharEncoding.UNICODE : CharEncoding.DEFAULT;
+        }
+        return result;
+    }
+
+    /**
+     * Sets the mapper between Java character sequences and the characters to write in WKT.
+     *
+     * <p>If this method is never invoked, or if this method is invoked with a {@code null} value,
+     * then the default mapper is {@link CharEncoding#DEFAULT} except for WKT formatted according
+     * the {@linkplain Convention#INTERNAL internal convention}.</p>
+     *
+     * @param encoding The new mapper to use, or {@code null} for restoring the default value.
+     *
+     * @since 0.6
+     */
+    public void setCharEncoding(final CharEncoding encoding) {
+        this.encoding = encoding;
+    }
+
+    /**
      * Returns whether non-ASCII characters are preserved. The default value is {@code false},
      * which causes replacements like "é" → "e" in all elements except {@link ElementKind#REMARKS}.
      *
@@ -233,9 +276,12 @@ public class WKTFormat extends CompoundF
      * @return Whether non-ASCII characters are preserved.
      *
      * @since 0.5
+     *
+     * @deprecated Replaced by {@link #getCharEncoding()}.
      */
+    @Deprecated
     public boolean isNonAsciiAllowed() {
-        return isNonAsciiAllowed || (convention == Convention.INTERNAL);
+        return getCharEncoding() == CharEncoding.UNICODE;
     }
 
     /**
@@ -246,9 +292,12 @@ public class WKTFormat extends CompoundF
      * @param allowed Whether non-ASCII characters shall be preserved.
      *
      * @since 0.5
+     *
+     * @deprecated Replaced by {@link #setCharEncoding(CharEncoding)}.
      */
+    @Deprecated
     public void setNonAsciiAllowed(final boolean allowed) {
-        isNonAsciiAllowed = allowed;
+        setCharEncoding(allowed ? CharEncoding.UNICODE : CharEncoding.DEFAULT);
     }
 
     /**
@@ -381,7 +430,9 @@ public class WKTFormat extends CompoundF
                 default: toUpperCase = (convention.majorVersion() == 1); break;
             }
             formatter.configure(convention, authority, colors, toUpperCase, indentation);
-            formatter.isNonAsciiAllowed |= isNonAsciiAllowed;
+            if (encoding != null) {
+                formatter.encoding = encoding;
+            }
         }
     }
 

Added: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java?rev=1675957&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java (added)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.io.wkt;
+
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.apache.sis.test.mock.CoordinateSystemAxisMock;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests the {@link CharEncoding} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+public final strictfp class CharEncodingTest extends TestCase {
+    /**
+     * Tests {@link CharEncoding#getAbbreviation(CoordinateSystem, CoordinateSystemAxis)}.
+     */
+    @Test
+    public void testGetAbbreviation() {
+        assertAbbreviationEquals("B", new Geographic("Geodetic latitude",    "φ"));
+        assertAbbreviationEquals("U", new Geocentric("Geocentric latitude",  "φ′"));
+        assertAbbreviationEquals("L", new Geographic("Geodetic longitude",   "λ"));
+        assertAbbreviationEquals("V", new Geocentric("Geocentric longitude", "θ"));
+    }
+
+    /**
+     * Asserts that the abbreviation of the given axis, after replacement of Greek letters,
+     * is equals to the expected string.
+     */
+    private static void assertAbbreviationEquals(final String expected, final CoordinateSystemAxisMock axis) {
+        assertEquals("abbreviation", expected, CharEncoding.DEFAULT.getAbbreviation(axis, axis));
+    }
+
+    /**
+     * A single axis which is part of a geographic CRS.
+     */
+    @SuppressWarnings("serial")
+    private static final class Geographic extends CoordinateSystemAxisMock implements EllipsoidalCS {
+        Geographic(final String name, final String abbreviation) {
+            super(name, abbreviation);
+        }
+    }
+
+    /**
+     * A single axis which is part of a geocentric CRS.
+     */
+    @SuppressWarnings("serial")
+    private static final class Geocentric extends CoordinateSystemAxisMock implements SphericalCS {
+        Geocentric(final String name, final String abbreviation) {
+            super(name, abbreviation);
+        }
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/CharEncodingTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/FormatterTest.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/FormatterTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/FormatterTest.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -58,6 +58,9 @@ public final strictfp class FormatterTes
     @Test
     public void testQuote() {
         assertWktEquals(Convention.WKT2,
+                "“A \"quote\" to replace”",             // Expect replacement of non-latin characters.
+                 "A “quote” to replace");
+        assertWktEquals(Convention.INTERNAL,
                 "“A “quote”” to double”",               // Expect doubling quotes.
                  "A “quote” to double");
         assertWktEquals(Convention.WKT2,

Copied: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java (from r1675811, sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java?p2=sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java&p1=sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java&r1=1675811&r2=1675957&rev=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/mock/CoordinateSystemAxisMock.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -16,95 +16,40 @@
  */
 package org.apache.sis.test.mock;
 
-import java.util.Date;
 import javax.measure.unit.Unit;
-import javax.measure.unit.SI;
-import javax.measure.unit.NonSI;
-import org.opengis.metadata.extent.Extent;
-import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.RangeMeaning;
-import org.opengis.referencing.cs.VerticalCS;
-import org.opengis.referencing.datum.VerticalDatum;
-import org.opengis.referencing.datum.VerticalDatumType;
-import org.opengis.util.InternationalString;
 
 
 /**
- * A dummy implementation of {@link VerticalCRS}, which is also its own datum, coordinate system and axis.
+ * A dummy implementation of {@link CoordinateSystemAxis}.
+ * Implements also {@link CoordinateSystem} for the purpose of tests which need some context.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.4
- * @version 0.4
+ * @since   0.6
+ * @version 0.6
  * @module
  */
 @SuppressWarnings("serial")
-public final strictfp class VerticalCRSMock extends IdentifiedObjectMock
-        implements VerticalCRS, VerticalDatum, VerticalCS, CoordinateSystemAxis
+public strictfp class CoordinateSystemAxisMock extends IdentifiedObjectMock
+        implements CoordinateSystemAxis, CoordinateSystem
 {
     /**
-     * Height in metres.
+     * The axis abbreviation.
      */
-    public static final VerticalCRS HEIGHT = new VerticalCRSMock("Height",
-            Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true);
+    final String abbreviation;
 
     /**
-     * Height in feet.
-     */
-    public static final VerticalCRS HEIGHT_ft = new VerticalCRSMock("Height",
-            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);
-
-    /**
-     * Depth in metres.
-     */
-    public static final VerticalCRS DEPTH = new VerticalCRSMock("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);
-
-    /**
-     * The minimum and maximum values.
-     */
-    private final double minimumValue, maximumValue;
-
-    /**
-     * The unit of measurement.
-     */
-    private final Unit<?> unit;
-
-    /**
-     * {@code true} if the axis direction is up, or {@code false} if down.
-     */
-    private final boolean up;
-
-    /**
-     * Creates a new vertical CRS for the given name.
+     * Creates a new axis for the given name.
      *
-     * @param name         The CRS, CS, datum and axis name.
-     * @param up           {@code true} if the axis direction is up, or {@code false} if down.
-     * @param unit         The unit of measurement.
-     * @param minimumValue The minium value.
-     * @param maximumValue The maximum value.
+     * @param name         The axis name.
+     * @param abbreviation The axis abbreviation.
      */
-    private VerticalCRSMock(final String name, final double minimumValue, final double maximumValue,
-            final Unit<?> unit, final boolean up)
-    {
+    public CoordinateSystemAxisMock(final String name, final String abbreviation) {
         super(name);
-        this.minimumValue = minimumValue;
-        this.maximumValue = maximumValue;
-        this.unit         = unit;
-        this.up           = up;
+        this.abbreviation = abbreviation;
     }
 
     /**
@@ -112,22 +57,15 @@ public final strictfp class VerticalCRSM
      */
     @Override
     Object[] properties() {
-        return new Object[] {getCode(), alias, minimumValue, maximumValue, unit, up};
+        return new Object[] {getCode(), alias, abbreviation};
     }
 
-    @Override public String               getAbbreviation()      {return up ? "h" : "d";}
-    @Override public InternationalString  getScope()             {return null;}
-    @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 VerticalDatum        getDatum()             {return this;}
-    @Override public VerticalCS           getCoordinateSystem()  {return this;}
+    @Override public String               getAbbreviation()      {return abbreviation;}
     @Override public int                  getDimension()         {return 1;}
     @Override public CoordinateSystemAxis getAxis(int dimension) {return this;}
-    @Override public AxisDirection        getDirection()         {return up ? AxisDirection.UP : AxisDirection.DOWN;}
-    @Override public double               getMinimumValue()      {return minimumValue;}
-    @Override public double               getMaximumValue()      {return maximumValue;}
+    @Override public AxisDirection        getDirection()         {return null;}
+    @Override public double               getMinimumValue()      {return Double.NEGATIVE_INFINITY;}
+    @Override public double               getMaximumValue()      {return Double.POSITIVE_INFINITY;}
     @Override public RangeMeaning         getRangeMeaning()      {return RangeMeaning.EXACT;}
-    @Override public Unit<?>              getUnit()              {return unit;}
+    @Override public Unit<?>              getUnit()              {return null;}
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -93,6 +93,7 @@ import org.junit.BeforeClass;
 
     org.apache.sis.io.wkt.ConventionTest.class,
     org.apache.sis.io.wkt.SymbolsTest.class,
+    org.apache.sis.io.wkt.CharEncodingTest.class,
     org.apache.sis.io.wkt.ColorsTest.class,
     org.apache.sis.io.wkt.FormatterTest.class,
     org.apache.sis.io.wkt.WKTFormatTest.class

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -35,7 +35,9 @@ import org.opengis.referencing.cs.RangeM
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.PolarCS;
 import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -50,6 +52,7 @@ import org.apache.sis.internal.jaxb.Cont
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.ElementKind;
+import org.apache.sis.io.wkt.CharEncoding;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 
 import static java.lang.Double.doubleToLongBits;
@@ -735,6 +738,26 @@ public class DefaultCoordinateSystemAxis
     }
 
     /**
+     * Returns the enclosing coordinate system, or {@code null} if none. In ISO 19162 compliant WKT the coordinate
+     * <strong>reference</strong> system should be the first parent ({@code formatter.getEnclosingElement(1)}) and
+     * the coordinate system shall be obtained from that CRS (yes, this is convolved. This is because of historical
+     * reasons, since compatibility with WKT 1 was a requirement of WKT 2). But we nevertheless walk over all parents
+     * in case someone format unusual things.
+     */
+    private static CoordinateSystem getEnclosingCS(final Formatter formatter) {
+        int depth = 1;
+        for (Object e; (e = formatter.getEnclosingElement(depth)) != null; depth++) {
+            if (e instanceof CoordinateReferenceSystem) {   // This is what we expect in standard WKT.
+                return ((CoordinateReferenceSystem) e).getCoordinateSystem();
+            }
+            if (e instanceof CoordinateSystem) {    // In case someone formats something unusual.
+                return (CoordinateSystem) e;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Formats this axis as a <cite>Well Known Text</cite> {@code Axis[…]} element.
      *
      * <div class="section">Constraints for WKT validity</div>
@@ -754,6 +777,9 @@ public class DefaultCoordinateSystemAxis
      *   <li>In {@link PolarCS}, replace “θ” abbreviation by <var>“U”</var>.</li>
      * </ul>
      *
+     * The above-cited replacements of Greek letters can be modified by calls to
+     * {@link org.apache.sis.io.wkt.WKTFormat#setCharEncoding(CharEncoding)}.
+     *
      * @return {@code "Axis"}.
      */
     @Override
@@ -780,51 +806,19 @@ public class DefaultCoordinateSystemAxis
          * The specification also suggests to write only the abbreviation (e.g. "(X)") in the
          * special case of Geocentric axis, and disallows Greek letters.
          */
-        String a = getAbbreviation();
-        if (!isWKT1 && (a != null) && !a.equals(name)) {
-            if (!isInternal && a.length() == 1) {
-                switch (a.charAt(0)) {
-                    /*
-                     * ISO 19162 §7.5.3 recommendations:
-                     *
-                     *   a) For PolarCS using Greek letter θ for direction, the letter ‘U’ should be used in WKT.
-                     *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
-                     */
-                    case 'θ': {
-                        final Object e = formatter.getEnclosingElement(0);
-                        if  (e instanceof SphericalCS) a ="V";
-                        else if (e instanceof PolarCS) a ="U";
-                        break;
-                    }
-                    /*
-                     * ISO 19162 §7.5.3 requirement (ii) and recommendation (b):
-                     *
-                     *  ii) Greek letters φ and λ for geodetic latitude and longitude must be replaced by Latin char.
-                     *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
-                     */
-                    case 'φ': {
-                        if (formatter.getEnclosingElement(0) instanceof SphericalCS) {
-                            a = "U";
-                        } else if ("Latitude".equalsIgnoreCase(name)) {
-                            a = "B";    // From German "Breite", used in academic texts worldwide.
-                        }
-                        break;
-                    }
-                    case 'λ': {
-                        if ("Longitude".equalsIgnoreCase(name)) {
-                            a = "L";    // From German "Länge", used in academic texts worldwide.
-                        }
-                        break;
-                    }
+        if (!isWKT1) {
+            final String a = formatter.getCharEncoding().getAbbreviation(getEnclosingCS(formatter), this);
+            if (a != null && !a.equals(name)) {
+                final StringBuilder buffer = new StringBuilder();
+                if (name != null) {
+                    buffer.append(name).append(' ');
                 }
+                name = buffer.append('(').append(a).append(')').toString();
             }
-            final StringBuilder buffer = new StringBuilder();
-            if (name != null) {
-                buffer.append(name).append(' ');
-            }
-            name = buffer.append('(').append(a).append(')').toString();
         }
-        formatter.append(name, ElementKind.AXIS);
+        if (name != null) {
+            formatter.append(name, ElementKind.AXIS);
+        }
         /*
          * Format the axis direction, optionally followed by a MERIDIAN[…] element
          * if the direction is of the kind "South along 90°N" for instance.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -19,7 +19,6 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
-import org.opengis.referencing.IdentifiedObject;
 import org.opengis.test.Validators;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
@@ -42,9 +41,9 @@ import static org.apache.sis.test.Metada
 /**
  * Tests the {@link AbstractReferenceSystem} class.
  *
- * @author  Martin Desruisseaux (IRD)
+ * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @DependsOn(AbstractIdentifiedObjectTest.class)
@@ -107,15 +106,18 @@ public final strictfp class AbstractRefe
                 new DefaultGeographicBoundingBox(2.54, 6.40, 51.43, 55.77),
                 new DefaultVerticalExtent(10, 1000, VerticalCRSMock.DEPTH),
                 new DefaultTemporalExtent()))); // TODO: needs sis-temporal module for testing that one.
-        final IdentifiedObject object = new AbstractReferenceSystem(properties);
+        final AbstractReferenceSystem object = new AbstractReferenceSystem(properties);
+
+        assertEquals( // Quotes (at least the closing one) conservatively omitted for WKT 1.
+                "ReferenceSystem[\"My object.\", AUTHORITY[\"EPSG\", \"4326\"]]",
+                object.toString(Convention.WKT1));
 
         assertWktEquals(Convention.WKT1,
-                // Closing quote conservatively omitted for WKT 1.
-                "ReferenceSystem[“My “object.”, AUTHORITY[“EPSG”, “4326”]]",
+                "ReferenceSystem[“My \"object\".”, AUTHORITY[“EPSG”, “4326”]]",
                 object);
 
         assertWktEquals(Convention.WKT2,
-                "ReferenceSystem[“My “object””.”,\n" +
+                "ReferenceSystem[“My \"object\".”,\n" +     // Quotes replaced
                 "  Scope[“Large scale topographic mapping and cadastre.”],\n" +
                 "  Area[“Netherlands offshore.”],\n" +
                 "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
@@ -125,7 +127,7 @@ public final strictfp class AbstractRefe
                 object);
 
         assertWktEquals(Convention.WKT2_SIMPLIFIED,
-                "ReferenceSystem[“My “object””.”,\n" +
+                "ReferenceSystem[“My \"object\".”,\n" +
                 "  Scope[“Large scale topographic mapping and cadastre.”],\n" +
                 "  Area[“Netherlands offshore.”],\n" +
                 "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
@@ -133,5 +135,15 @@ public final strictfp class AbstractRefe
                 "  Id[“EPSG”, 4326, “8.2”, Citation[“IOGP”], URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
                 "  Remarks[“注です。”]]",
                 object);
+
+        assertWktEquals(Convention.INTERNAL,
+                "ReferenceSystem[“My “object””.”,\n" +  // Quote doubled
+                "  Scope[“Large scale topographic mapping and cadastre.”],\n" +
+                "  Area[“Netherlands offshore.”],\n" +
+                "  BBox[51.43, 2.54, 55.77, 6.40],\n" +
+                "  VerticalExtent[-1000, -10],\n" +
+                "  Id[“EPSG”, 4326, “8.2”, Citation[“IOGP”]],\n" +
+                "  Remarks[“注です。”]]",
+                object);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -38,9 +38,9 @@ import static org.apache.sis.referencing
 /**
  * Tests the {@link DefaultCoordinateSystemAxis} class.
  *
- * @author  Martin Desruisseaux (IRD)
+ * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @DependsOn({
@@ -83,28 +83,32 @@ public final strictfp class DefaultCoord
 
     /**
      * Tests WKT formatting of predefined constants.
+     *
+     * Note that this method can not test the replacement of Greek letters by Latin letters in abbreviations,
+     * because those replacements depend on the {@code CoordinateSystem} context, which is not provided by
+     * this test method.
      */
     @Test
     public void testWKT() {
         assertWktEquals("Axis[“x”, east, LengthUnit[“metre”, 1]]",  X);
         assertWktEquals("Axis[“y”, north, LengthUnit[“metre”, 1]]", Y);
         assertWktEquals("Axis[“z”, up, LengthUnit[“metre”, 1]]",    Z);
-        assertWktEquals("Axis[“Longitude (L)”, east, AngleUnit[“grade”, 0.015707963267948967]]",            LONGITUDE_gon);
-        assertWktEquals("Axis[“Latitude (B)”, north, AngleUnit[“grade”, 0.015707963267948967]]",            LATITUDE_gon);
-        assertWktEquals("Axis[“Altitude (h)”, up, LengthUnit[“metre”, 1]]",                                 ALTITUDE);
-        assertWktEquals("Axis[“Time (t)”, future, TimeUnit[“day”, 86400]]",                                 TIME);
-        assertWktEquals("Axis[“Longitude (L)”, east, AngleUnit[“degree”, 0.017453292519943295]]",           GEODETIC_LONGITUDE);
-        assertWktEquals("Axis[“Spherical longitude (Ω)”, east, AngleUnit[“degree”, 0.017453292519943295]]", SPHERICAL_LONGITUDE);
-        assertWktEquals("Axis[“Latitude (B)”, north, AngleUnit[“degree”, 0.017453292519943295]]",           GEODETIC_LATITUDE);
-        assertWktEquals("Axis[“Spherical latitude (Θ)”, north, AngleUnit[“degree”, 0.017453292519943295]]", SPHERICAL_LATITUDE);
+        assertWktEquals("Axis[“Longitude (λ)”, east, AngleUnit[“grade”, 0.015707963267948967]]",             LONGITUDE_gon);
+        assertWktEquals("Axis[“Latitude (φ)”, north, AngleUnit[“grade”, 0.015707963267948967]]",             LATITUDE_gon);
+        assertWktEquals("Axis[“Altitude (h)”, up, LengthUnit[“metre”, 1]]",                                  ALTITUDE);
+        assertWktEquals("Axis[“Time (t)”, future, TimeUnit[“day”, 86400]]",                                  TIME);
+        assertWktEquals("Axis[“Longitude (λ)”, east, AngleUnit[“degree”, 0.017453292519943295]]",            GEODETIC_LONGITUDE);
+        assertWktEquals("Axis[“Spherical longitude (θ)”, east, AngleUnit[“degree”, 0.017453292519943295]]",  SPHERICAL_LONGITUDE);
+        assertWktEquals("Axis[“Latitude (φ)”, north, AngleUnit[“degree”, 0.017453292519943295]]",            GEODETIC_LATITUDE);
+        assertWktEquals("Axis[“Spherical latitude (φ')”, north, AngleUnit[“degree”, 0.017453292519943295]]", SPHERICAL_LATITUDE);
 
         assertWktEquals(Convention.WKT1,     "AXIS[“x”, EAST]",  X);
         assertWktEquals(Convention.WKT1,     "AXIS[“y”, NORTH]", Y);
         assertWktEquals(Convention.WKT1,     "AXIS[“z”, UP]",    Z);
-        assertWktEquals(Convention.INTERNAL, "Axis[“Geodetic longitude (λ)”, east, Unit[“degree”, 0.017453292519943295]]",  GEODETIC_LONGITUDE);
-        assertWktEquals(Convention.INTERNAL, "Axis[“Spherical longitude (Ω)”, east, Unit[“degree”, 0.017453292519943295]]", SPHERICAL_LONGITUDE);
-        assertWktEquals(Convention.INTERNAL, "Axis[“Geodetic latitude (φ)”, north, Unit[“degree”, 0.017453292519943295]]",  GEODETIC_LATITUDE);
-        assertWktEquals(Convention.INTERNAL, "Axis[“Spherical latitude (Θ)”, north, Unit[“degree”, 0.017453292519943295]]", SPHERICAL_LATITUDE);
+        assertWktEquals(Convention.INTERNAL, "Axis[“Geodetic longitude (λ)”, east, Unit[“degree”, 0.017453292519943295]]",   GEODETIC_LONGITUDE);
+        assertWktEquals(Convention.INTERNAL, "Axis[“Spherical longitude (θ)”, east, Unit[“degree”, 0.017453292519943295]]",  SPHERICAL_LONGITUDE);
+        assertWktEquals(Convention.INTERNAL, "Axis[“Geodetic latitude (φ)”, north, Unit[“degree”, 0.017453292519943295]]",   GEODETIC_LATITUDE);
+        assertWktEquals(Convention.INTERNAL, "Axis[“Spherical latitude (φ′)”, north, Unit[“degree”, 0.017453292519943295]]", SPHERICAL_LATITUDE);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -181,7 +181,7 @@ public final strictfp class HardCodedAxe
      * using {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical CS}.
      * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
      * and units are {@linkplain NonSI#DEGREE_ANGLE degrees}.
-     * The ISO 19111 name is <cite>"spherical longitude"</cite> and the abbreviation is "Ω" (omega).
+     * The ISO 19111 name is <cite>"spherical longitude"</cite> and the abbreviation is "θ" (theta).
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
@@ -189,7 +189,7 @@ public final strictfp class HardCodedAxe
      * @see #GEODETIC_LONGITUDE
      * @see #SPHERICAL_LATITUDE
      */
-    public static final DefaultCoordinateSystemAxis SPHERICAL_LONGITUDE = create("Spherical longitude", "Ω",
+    public static final DefaultCoordinateSystemAxis SPHERICAL_LONGITUDE = create("Spherical longitude", "θ",
             AxisDirection.EAST, NonSI.DEGREE_ANGLE, -180, 180, RangeMeaning.WRAPAROUND);
 
     /**
@@ -197,7 +197,7 @@ public final strictfp class HardCodedAxe
      * using {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical CS}.
      * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
      * and units are {@linkplain NonSI#DEGREE_ANGLE degrees}.
-     * The ISO 19111 name is <cite>"spherical latitude"</cite> and the abbreviation is "Θ" (theta).
+     * The ISO 19111 name is <cite>"spherical latitude"</cite> and the abbreviation is "φ′" (phi).
      *
      * <p>This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
      * {@link #GEOCENTRIC_RADIUS} set.</p>
@@ -205,7 +205,7 @@ public final strictfp class HardCodedAxe
      * @see #GEODETIC_LATITUDE
      * @see #SPHERICAL_LONGITUDE
      */
-    public static final DefaultCoordinateSystemAxis SPHERICAL_LATITUDE = create("Spherical latitude", "Θ",
+    public static final DefaultCoordinateSystemAxis SPHERICAL_LATITUDE = create("Spherical latitude", "φ′",
             AxisDirection.NORTH, NonSI.DEGREE_ANGLE, -90, 90, RangeMeaning.EXACT);
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -921,8 +921,14 @@ search:     for (; fromIndex <= toIndex;
      * Replaces some Unicode characters by ASCII characters on a "best effort basis".
      * For example the {@code 'é'} character is replaced by {@code 'e'} (without accent).
      *
-     * <p>The current implementation replaces only the characters in the range {@code 00C0}
-     * to {@code 00FF}, inclusive. Other characters are left unchanged.</p>
+     * <p>The current implementation replaces the characters in the range {@code 00C0}
+     * to {@code 00FF} (inclusive) and some space and punctuation characters.</p>
+     *
+     * <div class="note"><b>Note:</b>
+     * the replacement of Greek letters is a more complex task than what this method can do,
+     * since it depends on the context. For example if the Greek letters are abbreviations
+     * for coordinate system axes like φ and λ, then the replacements depend on the enclosing
+     * coordinate system. See {@link org.apache.sis.io.wkt.CharEncoding} for more information.</div>
      *
      * @param  text The text to scan for Unicode characters to replace by ASCII characters,
      *         or {@code null}.
@@ -930,6 +936,7 @@ search:     for (; fromIndex <= toIndex;
      *         has been applied, or {@code null} if the given text was null.
      *
      * @see StringBuilders#toASCII(StringBuilder)
+     * @see org.apache.sis.io.wkt.CharEncoding#filter(String)
      */
     public static CharSequence toASCII(final CharSequence text) {
         return StringBuilders.toASCII(text, null);

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -194,8 +194,8 @@ public final class StringBuilders extend
      * Replaces some Unicode characters by ASCII characters on a "best effort basis".
      * For example the {@code 'é'} character is replaced by {@code 'e'} (without accent).
      *
-     * <p>The current implementation replaces only the characters in the range {@code 00C0}
-     * to {@code 00FF}, inclusive. Other characters are left unchanged.</p>
+     * <p>The current implementation replaces the characters in the range {@code 00C0}
+     * to {@code 00FF} (inclusive) and some space and punctuation characters.</p>
      *
      * @param  buffer The text to scan for Unicode characters to replace by ASCII characters.
      * @throws NullArgumentException If the given {@code buffer} is null.
@@ -227,9 +227,19 @@ public final class StringBuilders extend
                         cr = ASCII.charAt(r);
                     } else {
                         switch (getType(c)) {
-                            case SPACE_SEPARATOR: cr = ' '; break;
-                            case PARAGRAPH_SEPARATOR: // Fall through
-                            case LINE_SEPARATOR: cr = '\n'; break;
+                            case PARAGRAPH_SEPARATOR:       // Fall through
+                            case LINE_SEPARATOR:            cr = '\n'; break;
+                            case SPACE_SEPARATOR:           cr = ' '; break;
+                            case INITIAL_QUOTE_PUNCTUATION: cr = (c == '‘') ? '\'' : '"'; break;
+                            case FINAL_QUOTE_PUNCTUATION:   cr = (c == '’') ? '\'' : '"'; break;
+                            case OTHER_PUNCTUATION: {
+                                switch (c) {
+                                    case '′': cr = '\''; break;
+                                    case '″': cr = '"';  break;
+                                    default:  continue;
+                                }
+                                break;
+                            }
                             default: continue;
                         }
                     }

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java?rev=1675957&r1=1675956&r2=1675957&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java [UTF-8] Fri Apr 24 21:27:48 2015
@@ -97,8 +97,10 @@ public final strictfp class StringBuilde
      */
     @Test
     public void testToASCII() {
-        final StringBuilder metre = new StringBuilder("mètres" + Characters.PARAGRAPH_SEPARATOR);
+        final StringBuilder metre = new StringBuilder(
+                "mètres" + Characters.PARAGRAPH_SEPARATOR +
+                " ‘single’, “double”, \"ascii' 30°20′10″.");
         toASCII(metre);
-        assertEquals("metres\n", metre.toString());
+        assertEquals("metres\n 'single', \"double\", \"ascii' 30°20'10\".", metre.toString());
     }
 }



Mime
View raw message