sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1783777 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/ main/java/org/apache/sis/referencing/gazetteer/ test/java/org/apache/sis/referencing/gazetteer/
Date Mon, 20 Feb 2017 15:25:42 GMT
Author: desruisseaux
Date: Mon Feb 20 15:25:42 2017
New Revision: 1783777

URL: http://svn.apache.org/viewvc?rev=1783777&view=rev
Log:
Fix the calculation of northing value and improve error messages.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
[UTF-8] Mon Feb 20 15:25:42 2017
@@ -166,6 +166,11 @@ public final class Resources extends Ind
         public static final short IllegalAxisDirection_2 = 20;
 
         /**
+         * “{0}” is not a valid latitude band. A letter was expected.
+         */
+        public static final short IllegalLatitudeBand_1 = 73;
+
+        /**
          * Dimensions of “{0}” operation can not be ({1} → {2}).
          */
         public static final short IllegalOperationDimension_3 = 21;
@@ -192,6 +197,16 @@ public final class Resources extends Ind
         public static final short IllegalParameterValue_2 = 25;
 
         /**
+         * “{0}” is not a valid square identification.
+         */
+        public static final short IllegalSquareIdentification_1 = 74;
+
+        /**
+         * “{0}” is not a valid Universal Transverse Mercator (UTM) zone.
+         */
+        public static final short IllegalUTMZone_1 = 72;
+
+        /**
          * Unit of measurement “{1}” is not valid for “{0}” values.
          */
         public static final short IllegalUnitFor_2 = 26;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
[ISO-8859-1] Mon Feb 20 15:25:42 2017
@@ -52,12 +52,15 @@ CoordinateOperationNotFound_2     = Coor
 DatumOriginShallBeDate            = Origin of temporal datum shall be a date.
 DuplicatedParameterName_4         = Name or alias for parameter \u201c{0}\u201d at index
{1} conflict with name \u201c{2}\u201d at index {3}.
 IllegalAxisDirection_2            = Coordinate system of class \u2018{0}\u2019 can not have
axis in the {1} direction.
+IllegalLatitudeBand_1             = \u201c{0}\u201d is not a valid latitude band. A letter
was expected.
 IllegalOperationDimension_3       = Dimensions of \u201c{0}\u201d operation can not be ({1}
\u2192 {2}).
 IllegalOperationForValueClass_1   = This operation can not be applied to values of class
\u2018{0}\u2019.
 IllegalParameterType_2            = Parameter \u201c{0}\u201d can not be of type \u2018{1}\u2019.
 IllegalParameterValue_2           = Parameter \u201c{0}\u201d can not take the \u201c{1}\u201d
value.
 IllegalParameterValueClass_3      = Parameter \u201c{0}\u201d does not accept values of \u2018{2}\u2019
type. Expected an instance of \u2018{1}\u2019 or derived type.
+IllegalSquareIdentification_1     = \u201c{0}\u201d is not a valid square identification.
 IllegalUnitFor_2                  = Unit of measurement \u201c{1}\u201d is not valid for
\u201c{0}\u201d values.
+IllegalUTMZone_1                  = \u201c{0}\u201d is not a valid Universal Transverse Mercator
(UTM) zone.
 IncompatibleCoordinateSystemTypes = Incompatible coordinate system types.
 IncompatibleDatum_2               = Datum of \u201c{1}\u201d shall be \u201c{0}\u201d.
 LatitudesAreOpposite_2            = Latitudes {0} and {1} are opposite.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
[ISO-8859-1] Mon Feb 20 15:25:42 2017
@@ -57,12 +57,15 @@ CoordinateOperationNotFound_2     = La c
 DatumOriginShallBeDate            = L\u2019origine d\u2019un r\u00e9f\u00e9rentiel temporel
doit \u00eatre une date.
 DuplicatedParameterName_4         = Le nom ou un alias pour le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb
\u00e0 l\u2019index {1} duplique le nom \u00ab\u202f{2}\u202f\u00bb \u00e0 l\u2019index {3}.
 IllegalAxisDirection_2            = Les syst\u00e8mes de coordonn\u00e9es de classe \u2018{0}\u2019
ne peuvent pas avoir d\u2019axe dans la direction \u00ab\u202f{1}\u202f\u00bb.
+IllegalLatitudeBand_1             = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas une bande
de latitude valide. Une lettre \u00e9tait attendue.
 IllegalOperationDimension_3       = Les dimensions de l\u2019op\u00e9ration \u00ab\u202f{0}\u202f\u00bb
ne peuvent pas \u00eatre ({1} \u2192 {2}).
 IllegalOperationForValueClass_1   = Cette op\u00e9ration ne peut pas s\u2019appliquer aux
valeurs de classe \u2018{0}\u2019.
 IllegalParameterType_2            = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb ne peut
pas \u00eatre du type \u2018{1}\u2019.
 IllegalParameterValue_2           = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb n\u2019accepte
pas la valeur \u00ab\u202f{1}\u202f\u00bb.
 IllegalParameterValueClass_3      = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb n\u2019accepte
pas les valeurs de type \u2018{2}\u2019. Une instance de \u2018{1}\u2019 ou d\u2019un type
d\u00e9riv\u00e9 \u00e9tait attendue.
+IllegalSquareIdentification_1     = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas un identifiant
de carr\u00e9 valide.
 IllegalUnitFor_2                  = L\u2019unit\u00e9 de mesure \u00ab\u202f{1}\u202f\u00bb
n\u2019est pas valide pour les valeurs de \u00ab\u202f{0}\u202f\u00bb.
+IllegalUTMZone_1                  = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas une zone valide
de la projection Transverse Mercator Universelle (UTM).
 IncompatibleCoordinateSystemTypes = Types de syst\u00e8mes de coordonn\u00e9es incompatibles.
 IncompatibleDatum_2               = Le r\u00e9f\u00e9rentiel de \u00ab\u202f{1}\u202f\u00bb
doit \u00eatre \u00ab\u202f{0}\u202f\u00bb.
 LatitudesAreOpposite_2            = Les latitudes {0} et {1} sont oppos\u00e9es.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
[UTF-8] Mon Feb 20 15:25:42 2017
@@ -76,6 +76,12 @@ final class MGRSEncoder {
     static final double GRID_SQUARE_SIZE = 100_000;
 
     /**
+     * Number of letters available for grid rows. Those letters are "ABCDEFGHJKLMNPQRSTUV"
(starting at letter
+     * F for zones of even number), repeated in a cycle. Each row is {@value #GRID_SQUARE_SIZE}
metres height.
+     */
+    static final int GRID_ROW_COUNT = 20;
+
+    /**
      * The number of digits in a one-meter precision when formatting MGRS labels.
      *
      * <p><b>Invariant:</b> the following relationship must hold:
@@ -319,7 +325,7 @@ final class MGRSEncoder {
                 if ((zone & 1) == 0) {
                     row += ('F' - 'A');
                 }
-                row = 'A' + (row % 20);
+                row = 'A' + (row % GRID_ROW_COUNT);
                 if (row >= EXCLUDE_I && ++row >= EXCLUDE_O) row++;
                 buffer.append(separator).append((char) col).append((char) row);
                 /*

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
[UTF-8] Mon Feb 20 15:25:42 2017
@@ -25,6 +25,7 @@ import org.opengis.referencing.crs.Proje
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.util.CharSequences;
@@ -32,6 +33,8 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.geometry.DirectPosition2D;
 
+import static org.apache.sis.referencing.gazetteer.MGRSEncoder.*;
+
 
 /**
  * The Military Grid Reference System (MGRS).
@@ -175,7 +178,7 @@ public class MilitaryGridReferenceSystem
          * @return precision of formatted labels in metres.
          */
         public double getPrecision() {
-            return MathFunctions.pow10(MGRSEncoder.METRE_PRECISION_DIGITS - digits);
+            return MathFunctions.pow10(METRE_PRECISION_DIGITS - digits);
         }
 
         /**
@@ -191,8 +194,8 @@ public class MilitaryGridReferenceSystem
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2,
"precision", precision));
             }
             // The -3 is an arbitrary limit to millimetre precision.
-            int n = Math.max(-3, Math.min(MGRSEncoder.METRE_PRECISION_DIGITS + 1, (int) p));
-            digits = (byte) (MGRSEncoder.METRE_PRECISION_DIGITS - n);
+            int n = Math.max(-3, Math.min(METRE_PRECISION_DIGITS + 1, (int) p));
+            digits = (byte) (METRE_PRECISION_DIGITS - n);
         }
 
         /**
@@ -256,60 +259,72 @@ public class MilitaryGridReferenceSystem
             ArgumentChecks.ensureNonNull("label", label);
             final int end  = CharSequences.skipTrailingWhitespaces(label, 0, label.length());
             final int base = CharSequences.skipLeadingWhitespaces (label, 0, end);
-            int i = base;
-            do if (i >= end) {
-                throw new GazetteerException(Errors.format(Errors.Keys.UnexpectedEndOfString_1,
label));
-            } while (isDigit(label.charAt(i++)));
-            final int zone = Integer.parseInt(label.subSequence(base, --i).toString());
+            int i = endOfDigits(label, base, end);
+            final int zone = parseInt(label, base, i, Resources.Keys.IllegalUTMZone_1);
             if (zone < 1 || zone > 60) {
-                throw new GazetteerException("Illegal UTM zone number: " + zone);       //
TODO: localize
+                throw new GazetteerException(Resources.format(Resources.Keys.IllegalUTMZone_1,
zone));
             }
             /*
              * Parse the sub-sequence made of letters. That sub-sequence can have one or
three parts.
              * The first part is mandatory and the two other parts are optional, but if the
two last
              * parts are omitted, then they must be omitted together.
              *
-             *   0: latitude band
-             *   1: column letter
-             *   2: row letter
+             *   1 — latitude band: C-X (excluding I and O) for UTM. Other letters (A,
B, Y, Z) are for UPS.
+             *   2 — column letter: A-H in zone 1, J-R (skipping O) in zone 2, S-Z in zone
3, then repeat.
+             *   3 — row letter:    ABCDEFGHJKLMNPQRSTUV in odd zones, FGHJKLMNPQRSTUVABCDE
in even zones.
              */
             double φ = Double.NaN;
             int col = 1, row = 0;
-            for (int part = 0; part <= 2; part++) {
-                i = skipSeparator(label, base, i, end);
+            for (int part = 1; part <= 3; part++) {
+                i = nextComponent(label, base, i, end, part != 2);
+                if (i >= end) {
+                    break;                                      // Allowed only for part
2 (the column letter).
+                }
                 int c = Character.codePointAt(label, i);
+                final int ni = i + Character.charCount(c);
                 if (c < 'A' || c > 'Z') {
                     if (c >= 'a' && c <= 'z') {
                         c -= ('a' - 'A');
                     } else {
-                        // TODO: specialize the error message for band, col and row.
-                        throw new GazetteerException("Illegal latitude band: " +
-                                label.subSequence(i, i + Character.charCount(c)));
+                        final short key;
+                        final CharSequence token;
+                        if (part == 1) {
+                            key = Resources.Keys.IllegalLatitudeBand_1;
+                            token = label.subSequence(i, ni);
+                        } else {
+                            key = Resources.Keys.IllegalSquareIdentification_1;
+                            token = CharSequences.token(label, i);
+                        }
+                        throw new GazetteerException(Resources.format(key, token));
                     }
                 }
+                /*
+                 * At this point, 'c' is a valid letter. First, applies a correction for
the fact that 'I' and 'O'
+                 * letters were excluded. Next, the conversion to latitude or 100 000 meters
grid indices depends
+                 * on which part we are parsing. The formulas used below are about the same
than in MGRSEncoder,
+                 * with terms moved on the other side of the equations.
+                 */
+                if (c >= EXCLUDE_O) c--;
+                if (c >= EXCLUDE_I) c--;
                 switch (part) {
-                    case 0: {
-                        if (c >= MGRSEncoder.EXCLUDE_O) c--;
-                        if (c >= MGRSEncoder.EXCLUDE_I) c--;
-                        φ = (c - 'C') * MGRSEncoder.LATITUDE_BAND_HEIGHT + TransverseMercator.Zoner.SOUTH_BOUNDS;
+                    case 1: {
+                        φ = (c - 'C') * LATITUDE_BAND_HEIGHT + TransverseMercator.Zoner.SOUTH_BOUNDS;
                         break;
                     }
-                    case 1: {
+                    case 2: {
                         switch (zone % 3) {                         // First A-H sequence
starts at zone number 1.
                             case 1: col = c - ('A' - 1); break;
-                            case 2: col = c - ('J' - 1); if (c >= MGRSEncoder.EXCLUDE_O)
col--; break;
-                            case 0: col = c - ('S' - 1); break;
+                            case 2: col = c - ('J' - 2); break;     // -2 because 'I' has
already been excluded.
+                            case 0: col = c - ('S' - 3); break;     // -3 because 'I' and
'O' have been excluded.
                         }
                         break;
                     }
-                    case 2: {
-                        if (c >= MGRSEncoder.EXCLUDE_O) c--;
-                        if (c >= MGRSEncoder.EXCLUDE_I) c--;
-                        row = c - (((zone & 1) != 0) ? 'F' : 'A');
+                    case 3: {
+                        row = c - (((zone & 1) == 0) ? 'F' : 'A');
                         break;
                     }
                 }
-                i++;
+                i = ni;
             }
             /*
              * We need to create a UTM projection from (φ,λ) coordinates, not from UTM
zone,
@@ -317,30 +332,33 @@ public class MilitaryGridReferenceSystem
              */
             final double λ = TransverseMercator.Zoner.UTM.centralMeridian(zone);
             final ProjectedCRS crs = datum.universal(φ,λ);
-            DirectPosition2D p = new DirectPosition2D(φ,λ);
-            DirectPosition c = crs.getConversionFromBase().getMathTransform().transform(p,
p);
-            row += ((int) (c.getOrdinate(1) / (MGRSEncoder.GRID_SQUARE_SIZE * 20))) * 20;
-
-            final DirectPosition2D pos = new DirectPosition2D(crs);
-            pos.x = col * MGRSEncoder.GRID_SQUARE_SIZE;
-            pos.y = row * MGRSEncoder.GRID_SQUARE_SIZE;
+            final DirectPosition2D pos = new DirectPosition2D(φ,λ);
+            row += ((int) (crs.getConversionFromBase().getMathTransform().transform(pos,
pos).getOrdinate(1)
+                    / (GRID_SQUARE_SIZE * GRID_ROW_COUNT))) * GRID_ROW_COUNT;
+
+            pos.setCoordinateReferenceSystem(crs);
+            pos.x = col * GRID_SQUARE_SIZE;
+            pos.y = row * GRID_SQUARE_SIZE;
             return pos;
         }
 
         /**
          * Skips spaces, then the separator if present (optional).
          *
-         * @param  label  the label to parse.
-         * @param  base   index where the parsing began. Used for formatting error message
only.
-         * @param  start  current parsing position.
-         * @param  end    where the parsing is expected to end.
-         * @return position where to continue parsing, with spaces skipped.
+         * @param  label      the label to parse.
+         * @param  base       index where the parsing began. Used for formatting error message
only.
+         * @param  start      current parsing position.
+         * @param  end        where the parsing is expected to end.
+         * @param  mandatory  whether to throw an exception or return {@code end} if we reached
the end of string.
+         * @return position where to continue parsing (with spaces skipped), or {@code end}
if we reached end of string.
          * @throws GazetteerException if this method unexpectedly reached the end of string.
          */
-        private int skipSeparator(final CharSequence label, final int base, int start, final
int end) throws GazetteerException {
+        private int nextComponent(final CharSequence label, final int base, int start, final
int end, final boolean mandatory)
+                throws GazetteerException
+        {
             start = CharSequences.skipLeadingWhitespaces(label, start, end);
             if (start < end) {
-                if (!CharSequences.regionMatches(label, start, separator)) {
+                if (!CharSequences.regionMatches(label, start, trimmedSeparator)) {
                     return start;               // Separator not found, but it was optional.
                 }
                 start += trimmedSeparator.length();
@@ -349,15 +367,52 @@ public class MilitaryGridReferenceSystem
                     return start;
                 }
             }
+            if (!mandatory) return start;
             throw new GazetteerException(Errors.format(Errors.Keys.UnexpectedEndOfString_1,
label.subSequence(base, end)));
         }
     }
 
     /**
-     * Returns whether the given character is an ASCII digit. We do not use {@link Character#isDigit(char)}
-     * because we restrict to the set of ASCII characters.
+     * Returns the index after the last digit in a sequence of ASCII characters.
+     * Leading whitespaces must have been skipped before to invoke this method.
      */
-    static boolean isDigit(final char c) {
-        return c >= '0' && c <= '9';
+    static int endOfDigits(final CharSequence label, int i, final int end) {
+        while (i < end) {
+            final char c = label.charAt(i);     // Code-point API not needed here because
we restrict to ASCII.
+            if (c < '0' || c > '9') {           // Do not use Character.isDigit(…)
because we restrict to ASCII.
+                break;
+            }
+            i++;
+        }
+        return i;
+    }
+
+    /**
+     * Parses part of the given character sequence as an integer.
+     *
+     * @param  label     the MGRS label to parse.
+     * @param  start     index of the first character to parse as an integer.
+     * @param  end       index after the last character to parse as an integer.
+     * @param  errorKey  {@link Resources.Keys} value to use in case of error.
+     *                   The error message string shall accept exactly one argument.
+     * @return the parsed integer.
+     * @throws GazetteerException if the string can not be parsed as an integer.
+     */
+    static int parseInt(final CharSequence label, final int start, final int end, final short
errorKey)
+            throws GazetteerException
+    {
+        NumberFormatException cause = null;
+        final CharSequence part;
+        if (start == end) {
+            part = CharSequences.token(label, start);
+        } else {
+            part = label.subSequence(start, end);
+            try {
+                return Integer.parseInt(part.toString());
+            } catch (NumberFormatException e) {
+                cause = e;
+            }
+        }
+        throw new GazetteerException(Resources.format(errorKey, part), cause);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java?rev=1783777&r1=1783776&r2=1783777&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
[UTF-8] Mon Feb 20 15:25:42 2017
@@ -162,8 +162,10 @@ public final strictfp class MilitaryGrid
     @Test
     public void testDecoding() throws TransformException {
         final MilitaryGridReferenceSystem.Coder coder = coder();
+        coder.setSeparator(" / ");
         final DirectPosition position = coder.decode("32TNL8410239239");
+        assertEquals("32TNL8410239239", position, coder.decode("32/T/NL/84102/39239"));
         assertEquals("Easting",   500000, position.getOrdinate(0), STRICT);
-//      assertEquals("Northing", 4500000, position.getOrdinate(1), STRICT);
+        assertEquals("Northing", 4500000, position.getOrdinate(1), STRICT);
     }
 }



Mime
View raw message