You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/03/06 17:29:29 UTC

svn commit: r1785697 - in /sis/branches/JDK8/core/sis-referencing-by-identifiers/src: main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java

Author: desruisseaux
Date: Mon Mar  6 17:29:29 2017
New Revision: 1785697

URL: http://svn.apache.org/viewvc?rev=1785697&view=rev
Log:
Enable clipping of MGRS cell in domain of validity of their UTM zone.

Modified:
    sis/branches/JDK8/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
    sis/branches/JDK8/core/sis-referencing-by-identifiers/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java

Modified: sis/branches/JDK8/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java?rev=1785697&r1=1785696&r2=1785697&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java [UTF-8] Mon Mar  6 17:29:29 2017
@@ -329,7 +329,7 @@ public class MilitaryGridReferenceSystem
         private final Map<CoordinateReferenceSystem,Encoder> encoders;
 
         /**
-         * Temporary positions used for encoding and decoding. References are kept for avoiding
+         * Temporary positions used for encoding. References are kept for avoiding
          * to recreate those temporary objects for every reference to parse or format.
          */
         transient DirectPosition normalized, geographic;
@@ -900,7 +900,7 @@ public class MilitaryGridReferenceSystem
         Decoder(final Coder owner, final CharSequence reference) throws TransformException {
             super(owner.getReferenceSystem().rootType(), reference);
             final int zone;                     // UTM zone, or 0 if UPS.
-            boolean hasSquareIdentification;    // Whether a square identification is present (UTM only).
+            boolean hasSquareIdentification;    // Whether a square identification is present.
             final double \u03c6s;                    // Southernmost bound of latitude band (UTM only).
             final double \u03bb0;                    // Central meridian of UTM zone (ignoring Norway and Svalbard).
             boolean isValid = true;             // Whether the given reference passes consistency checks.
@@ -972,7 +972,7 @@ parse:                  switch (part) {
                 crs  = owner.projection(\u03c6s = (south ? Latitude.MIN_VALUE : Latitude.MAX_VALUE), 0);
                 minX = col * GRID_SQUARE_SIZE;
                 minY = row * GRID_SQUARE_SIZE;
-                hasSquareIdentification = false;
+                hasSquareIdentification = true;
                 \u03bb0 = 0;
             } else {
                 /*
@@ -1178,22 +1178,8 @@ parse:                  switch (part) {
                     eastBoundLongitude = Longitude.MAX_VALUE;
                 }
             } else {
-                final MathTransform inverse = crs.getConversionFromBase().getMathTransform().inverse();
-                computeGeographicBoundingBox(inverse);
-                final boolean changed;
-                if (zone != 0) {
-                    changed = clipGeographicBoundingBox(\u03bb0 - ZONER.width/2, \u03c6s,
-                                                        \u03bb0 + ZONER.width/2, \u03c6s + LATITUDE_BAND_HEIGHT);
-                } else if (\u03c6s < 0) {
-                    changed = clipGeographicBoundingBox(Longitude.MIN_VALUE, Latitude.MIN_VALUE,
-                                                        Longitude.MAX_VALUE, TransverseMercator.Zoner.SOUTH_BOUNDS);
-                } else {
-                    changed = clipGeographicBoundingBox(Longitude.MIN_VALUE, TransverseMercator.Zoner.NORTH_BOUNDS,
-                                                        Longitude.MAX_VALUE, Latitude.MAX_VALUE);
-                }
-                if (changed) {
-//                  clipProjectedEnvelope(inverse.inverse(), sx / 100, sy / 100);       // TODO
-                }
+                final MathTransform projection = crs.getConversionFromBase().getMathTransform();
+                computeGeographicBoundingBox(projection.inverse());
                 /*
                  * At this point we finished computing the position. Now perform error detection, by verifying
                  * if the given 100 kilometres square identification is consistent with grid zone designation.
@@ -1204,12 +1190,10 @@ parse:                  switch (part) {
                  * tolerance threshold for the upper bound because the coordinate that we are testing is the
                  * lower-left corner of the cell area.
                  */
-                if (isValid) {
-                    final DirectPosition geographic = inverse.transform(getDirectPosition(), owner.geographic);
-                    final double \u03bb = geographic.getOrdinate(1);
-                    final double \u03c6 = geographic.getOrdinate(0);
-                    owner.geographic = geographic;                                          // For future reuse.
-                    isValid = (\u03c6 >= \u03c6s - LATITUDE_BAND_HEIGHT/2) && (\u03c6 < upperBounds(\u03c6s));  // See above comment.
+                if (isValid && zone != 0) {
+                    final double \u03bb = (westBoundLongitude + eastBoundLongitude) / 2;
+                    final double \u03c6 = (southBoundLatitude + northBoundLatitude) / 2;
+                    isValid = (\u03c6 >= \u03c6s - LATITUDE_BAND_HEIGHT/2) && (\u03c6 < upperBound(\u03c6s));   // See above comment.
                     if (isValid) {
                         /*
                          * Verification of UTM zone. We allow a tolerance for latitudes close to a pole because
@@ -1234,6 +1218,29 @@ parse:                  switch (part) {
                         }
                     }
                 }
+                /*
+                 * At this point we finished verifying the cell validity using the coordinates specified by the
+                 * MGRS reference. If the cell is valid, we can now check for cells that are on a zone border.
+                 * Those cells will be clipped to the zone valid area.
+                 */
+                if (isValid) {
+                    final boolean changed;
+                    if (zone != 0) {
+                        double width = ZONER.width;
+                        if (!ZONER.isSpecialCase(zone, \u03c6s)) width /= 2;       // Be strict only if not Norway or Svalbard.
+                        changed = clipGeographicBoundingBox(\u03bb0 - width, \u03c6s,
+                                                            \u03bb0 + width, upperBound(\u03c6s));
+                    } else if (\u03c6s < 0) {
+                        changed = clipGeographicBoundingBox(Longitude.MIN_VALUE, Latitude.MIN_VALUE,
+                                                            Longitude.MAX_VALUE, TransverseMercator.Zoner.SOUTH_BOUNDS);
+                    } else {
+                        changed = clipGeographicBoundingBox(Longitude.MIN_VALUE, TransverseMercator.Zoner.NORTH_BOUNDS,
+                                                            Longitude.MAX_VALUE, Latitude.MAX_VALUE);
+                    }
+                    if (changed) {
+                        clipProjectedEnvelope(projection, sx / 100, sy / 100);
+                    }
+                }
             }
             if (!isValid) {
                 final String gzd;
@@ -1343,9 +1350,9 @@ parse:                  switch (part) {
         }
 
         /**
-         * Returns the upper bounds of the latitude band specified by the given lower bounds.
+         * Returns the upper bound of the latitude band specified by the given lower bound.
          */
-        static double upperBounds(final double \u03c6) {
+        static double upperBound(final double \u03c6) {
             return \u03c6 < TransverseMercator.Zoner.SVALBARD_BOUNDS ? \u03c6 + LATITUDE_BAND_HEIGHT
                      : TransverseMercator.Zoner.NORTH_BOUNDS;
         }

Modified: sis/branches/JDK8/core/sis-referencing-by-identifiers/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing-by-identifiers/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java?rev=1785697&r1=1785696&r2=1785697&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing-by-identifiers/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing-by-identifiers/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java [UTF-8] Mon Mar  6 17:29:29 2017
@@ -160,7 +160,7 @@ public final strictfp class MilitaryGrid
              * The result is that we will have some overlap in the northing value of consecutive latitude bands.
              */
             geographic.y = isSouth ? zoneCentre : zoneBorder;
-            geographic.x = MilitaryGridReferenceSystem.Decoder.upperBounds(\u03c6);
+            geographic.x = MilitaryGridReferenceSystem.Decoder.upperBound(\u03c6);
             final double ymax = projection.transform(geographic, projected).getOrdinate(1);
             /*
              * Computes the value that we will encode in the MilitaryGridReferenceSystem.Decoder.ROW_RESOLVER table.
@@ -313,26 +313,38 @@ public final strictfp class MilitaryGrid
     public void testDecodeLimitCases() throws TransformException {
         final MilitaryGridReferenceSystem.Coder coder = coder();
         DirectPosition position;
-
+        /*
+         * Cell on the West border of a UTM zone in the South hemisphere.
+         * The Easting value would be 250000 if the cell was not clipped.
+         */
         position = decode(coder, "19JBK");                                            // South hemisphere
         assertSame("crs", CommonCRS.WGS84.universal(-10, -69), position.getCoordinateReferenceSystem());
-        assertEquals("Easting",   250000, position.getOrdinate(0), STRICT);
+        assertEquals("Easting",   251256, position.getOrdinate(0), 1);
         assertEquals("Northing", 6950000, position.getOrdinate(1), STRICT);
-
+        /*
+         * Easting range before clipping is [300000 \u2026 400000] metres.
+         * The east boung become 343828 metres after clipping.
+         * The easting value would be 350000 if the cell was not clipped.
+         */
         position = decode(coder, "1VCK");                                // North of Norway latitude band
         assertSame("crs", CommonCRS.WGS84.universal(62, -180), position.getCoordinateReferenceSystem());
-        assertEquals("Easting",   350000, position.getOrdinate(0), STRICT);
+        assertEquals("Easting",   371914, position.getOrdinate(0), 1);
         assertEquals("Northing", 6950000, position.getOrdinate(1), STRICT);
-
+        /*
+         * Northing value would be 7350000 if the cell was not clipped.
+         */
         position = decode(coder, "57KTP");
         assertSame("crs", CommonCRS.WGS84.universal(-24, 156), position.getCoordinateReferenceSystem());
         assertEquals("Easting",   250000, position.getOrdinate(0), STRICT);
-        assertEquals("Northing", 7350000, position.getOrdinate(1), STRICT);
-
+        assertEquals("Northing", 7371306, position.getOrdinate(1), 1);
+        /*
+         * Easting  value would be  650000 if the cell was not clipped.
+         * Northing value would be 6250000 if the cell was not clipped.
+         */
         position = decode(coder, "56VPH");
         assertSame("crs", CommonCRS.WGS84.universal(55, 154), position.getCoordinateReferenceSystem());
-        assertEquals("Easting",   650000, position.getOrdinate(0), STRICT);
-        assertEquals("Northing", 6250000, position.getOrdinate(1), STRICT);
+        assertEquals("Easting",   643536, position.getOrdinate(0), 1);
+        assertEquals("Northing", 6253618, position.getOrdinate(1), 1);
     }
 
     /**