sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1782798 - in /sis/branches/JDK8: core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ core/sis-referencing/src/main/java/org/apache/sis/referencing/ core/sis-referencing/src/main/java/org/apache/sis/referencing/...
Date Mon, 13 Feb 2017 16:11:48 GMT
Author: desruisseaux
Date: Mon Feb 13 16:11:47 2017
New Revision: 1782798

URL: http://svn.apache.org/viewvc?rev=1782798&view=rev
Log:
Begin a skeleton of "referencing by geographic identifiers" package, using MGRS as a first
system.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
  (with props)
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
  (with props)
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
      - copied, changed from r1782301, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
  (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/GeoHashCoder.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -157,7 +157,7 @@ public final class TransverseMercator ex
 
         /**
          * Computes zones for the Modified Transverse Mercator (MTM) projections.
-         * This projection is in used in Canada only.
+         * This projection is used in Canada only.
          *
          * <blockquote><table class="sis">
          *   <caption>Modified Transverse Mercator parameters</caption>
@@ -220,8 +220,8 @@ public final class TransverseMercator ex
          *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
          *   <tr><td>Latitude of natural origin</td>     <td>Given
latitude, or 0° if zoned projection</td></tr>
          *   <tr><td>Longitude of natural origin</td>    <td>Given
longitude, optionally snapped to a zone central meridian</td></tr>
-         *   <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr>
-         *   <tr><td>False easting</td>                  <td>500000
metres</td></tr>
+         *   <tr><td>Scale factor at natural origin</td> <td>0.9996
for UTM or 0.9999 for MTM</td></tr>
+         *   <tr><td>False easting</td>                  <td>500000
metres for UTM or 304800 metres for MTM</td></tr>
          *   <tr><td>False northing</td>                 <td>0 (North
hemisphere) or 10000000 (South hemisphere) metres</td></tr>
          * </table></blockquote>
          *
@@ -232,7 +232,7 @@ public final class TransverseMercator ex
          * @return a name like <cite>"Transverse Mercator"</cite> or <cite>"UTM
zone 10N"</cite>,
          *         depending on the arguments given to this method.
          */
-        public String setParameters(final ParameterValueGroup group,
+        public final String setParameters(final ParameterValueGroup group,
                 final boolean zoned, double latitude, double longitude)
         {
             final boolean isSouth = MathFunctions.isNegative(latitude);
@@ -256,14 +256,14 @@ public final class TransverseMercator ex
         }
 
         /**
-         * If the given parameter values are those of an UTM projection, returns the zone
number (negative if South).
+         * If the given parameter values are those of a zoned projection, returns the zone
number (negative if South).
          * Otherwise returns 0. It is caller's responsibility to verify that the operation
method is {@value #NAME}.
          *
          * @param  group  the Transverse Mercator projection parameters.
-         * @return UTM zone number (positive if North, negative if South),
-         *         or 0 if the given parameters are not for a UTM projection.
+         * @return zone number (positive if North, negative if South),
+         *         or 0 if the given parameters are not for a zoned projection.
          */
-        public int zone(final ParameterValueGroup group) {
+        public final int zone(final ParameterValueGroup group) {
             if (Numerics.epsilonEqual(group.parameter(Constants.SCALE_FACTOR)      .doubleValue(Units.UNITY),
scale,   Numerics.COMPARISON_THRESHOLD) &&
                 Numerics.epsilonEqual(group.parameter(Constants.FALSE_EASTING)     .doubleValue(Units.METRE),
easting, Formulas.LINEAR_TOLERANCE) &&
                 Numerics.epsilonEqual(group.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(Units.DEGREE),
     0, Formulas.ANGULAR_TOLERANCE))
@@ -283,13 +283,13 @@ public final class TransverseMercator ex
         }
 
         /**
-         * Computes the UTM zone from a meridian in the zone.
+         * Computes the zone from a meridian in the zone.
          *
          * @param  longitude  a meridian inside the desired zone, in degrees relative to
Greenwich.
          *                    Positive longitudes are toward east, and negative longitudes
toward west.
-         * @return the UTM zone number numbered from 1 to 60 inclusive, or 0 if the given
central meridian was NaN.
+         * @return the zone number numbered from 1 inclusive, or 0 if the given central meridian
was NaN.
          */
-        public int zone(double longitude) {
+        public final int zone(double longitude) {
             /*
              * Casts to int are equivalent to Math.floor(double) for positive values, which
is guaranteed
              * to be the case here since we normalize the central meridian to the [MIN_VALUE
… MAX_VALUE] range.
@@ -301,12 +301,12 @@ public final class TransverseMercator ex
         }
 
         /**
-         * Computes the central meridian of a given UTM zone.
+         * Computes the central meridian of a given zone.
          *
-         * @param  zone  the UTM zone as a number in the [1 … 60] range.
-         * @return the central meridian of the given UTM zone.
+         * @param  zone  the zone as a number starting with 1.
+         * @return the central meridian of the given zone.
          */
-        public double centralMeridian(final int zone) {
+        public final double centralMeridian(final int zone) {
             return (zone - 0.5) * width + origin;
         }
     }

Added: 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=1782798&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -0,0 +1,258 @@
+/*
+ * 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.referencing.gazetteer;
+
+import org.opengis.util.FactoryException;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.referencing.crs.DefaultGeographicCRS;
+import org.apache.sis.referencing.crs.DefaultProjectedCRS;
+import org.apache.sis.referencing.cs.AxesConvention;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.resources.Errors;
+
+
+/**
+ * Conversions from direct positions to Military Grid Reference System (MGRS) labels.
+ * Each {@code MGRSEncoder} instance is configured for one {@code DirectPosition} CRS.
+ * If a position is given in another CRS, another {@code MGRSEncoder} instance must be created.
+ *
+ * <div class="section">Immutability and thread safety</div>
+ * This class is <strong>not</strong> thread-safe. A new instance must be created
for each thread,
+ * or synchronization must be applied by the caller.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Military_Grid_Reference_System">Military
Grid Reference System on Wikipedia</a>
+ */
+final class MGRSEncoder {
+    /**
+     * Height of latitude bands, in degrees.
+     * Those bands are labeled from {@code 'C'} to {@code 'X'} inclusive, excluding {@code
'I'} and {@code 'O'}.
+     */
+    private static final double LATITUDE_BAND_HEIGHT = 8;
+
+    /**
+     * Southernmost bound of the first latitude band ({@code 'C'}).
+     */
+    private static final double UTM_SOUTH_BOUNDS = -80;
+
+    /**
+     * Northernmost bound of the last latitude band ({@code 'X'}).
+     */
+    private static final double UTM_NORTH_BOUNDS = 84;
+
+    /**
+     * Size of the 100,000-meter squares.
+     */
+    private static final double GRID_SQUARE_SIZE = 100_000;
+
+    /**
+     * UTM zone of position CRS (negative for South hemisphere), or 0 if that CRS is not
an UTM projection.
+     * Note that this is not necessarily the same zone than the one to use for formatting
any given coordinate
+     * in that projected CRS, since the {@link #zone(double, char)} method has special rules
for some latitudes.
+     */
+    private int crsZone;
+
+    /**
+     * Coordinate conversion from the position CRS to a CRS of the same type but with normalized
axes.
+     * Axis directions are (East, North) and axis units are metres or degrees, depending
on the CRS type.
+     */
+    private MathTransform toNormalized;
+
+    /**
+     * Coordinate conversion from the <em>normalized</em> position CRS to a normalized
geographic CRS.
+     * Axis directions are (East, North) and axis units are degrees.
+     */
+    private MathTransform toGeographic;
+
+    /**
+     * Creates a new converter from direct positions to MGRS labels.
+     */
+    MGRSEncoder(final CoordinateReferenceSystem crs) throws FactoryException, TransformException
{
+        if (crs == null) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.UnspecifiedCRS));
+        }
+        if (crs instanceof ProjectedCRS) {
+            Projection projection = ((ProjectedCRS) crs).getConversionFromBase();
+            final OperationMethod method = projection.getMethod();
+            if (IdentifiedObjects.isHeuristicMatchForName(method, TransverseMercator.NAME))
{
+                crsZone = TransverseMercator.Zoner.UTM.zone(projection.getParameterValues());
+                if (crsZone != 0) {
+                    /*
+                     * Usually, the projected CRS already has (E,N) axis orientations with
metres units,
+                     * so we let 'toNormalized' to null. In the rarer cases where the CRS
axes do not
+                     * have the expected orientations and units, then we build a normalized
version of
+                     * that CRS and compute the transformation to that CRS.
+                     */
+                    DefaultProjectedCRS normalized = DefaultProjectedCRS.castOrCopy((ProjectedCRS)
crs);
+                    if (normalized != (normalized = normalized.forConvention(AxesConvention.NORMALIZED)))
{
+                        toNormalized = CRS.findOperation(crs, normalized, null).getMathTransform();
+                        projection = normalized.getConversionFromBase();
+                    }
+                    /*
+                     * We will also need the transformation from the normalized projected
CRS to longitude
+                     * and latitude (in that order) in degrees. We can get this transform
directly from the
+                     * projected CRS if its base CRS already has the expected axis orientations
and units.
+                     */
+                    DefaultGeographicCRS geographic = DefaultGeographicCRS.castOrCopy(normalized.getBaseCRS());
+                    if (geographic != (geographic = geographic.forConvention(AxesConvention.NORMALIZED)))
{
+                        toGeographic = CRS.findOperation(normalized, geographic, null).getMathTransform();
+                    } else {
+                        toGeographic = projection.getMathTransform().inverse();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the band letter for the given latitude. It is caller responsibility to ensure
that the
+     * given latitude is between {@value #UTM_SOUTH_BOUNDS} and {@value #UTM_NORTH_BOUNDS}
inclusive.
+     * The returned letter will be one of {@code "CDEFGHJKLMNPQRSTUVWX"} (note that I and
O letters
+     * are excluded). All bands are 8° height except the X band which is 12° height.
+     *
+     * @param  φ  the latitude in degrees for which to get the band letter.
+     * @return the band letter for the given latitude.
+     */
+    static char latitudeBand(final double φ) {
+        int band = 'C' + (int) ((φ - UTM_SOUTH_BOUNDS) / LATITUDE_BAND_HEIGHT);
+        if (band >= 'N') {
+            if (band == 'W') {
+                band++;             // Because the last latitude band ('X') is 12° height
instead of 8°.
+            } else {
+                band += 2;
+            }
+        } else if (band >= 'I') {
+            band++;
+        }
+        return (char) band;
+    }
+
+    /**
+     * Computes the UTM zone for the given longitude and latitude band.
+     * Those zones are normally the same than UTM, except for Norway and
+     * Svalbard which have special rules.
+     *
+     * @param  zone  the value of {@code TransverseMercator.Zoner.UTM.zone(λ)}.
+     * @param  band  the latitude band computed by {@link #latitudeBand(double)}.
+     * @param  λ     the longitude for which to compute the UTM zone.
+     * @return the UTM zone for the given longitude.
+     */
+    static int zone(int zone, final double λ, final char band) {
+        switch (band) {
+            /*
+             * Zone 32 has been widened to 9° (at the expense of zone 31)
+             * between latitudes 56° and 64° to accommodate southwest Norway.
+             */
+            case 'V': {
+                if (zone == 31 && λ >= 3) zone++;           // 3° is the central
meridian of zone 31.
+                break;
+            }
+            /*
+             * Between 72° and 84°, zones 33 and 35 have been widened to 12° to accommodate
Svalbard.
+             * To compensate for these 12° wide zones, zones 31 and 37 are widened to 9°
and zones 32,
+             * 34, and 36 are eliminated.
+             */
+            case 'X': {
+                switch (zone) {
+                    case 32: if (λ >=  9) zone++; else zone--; break;   //  9° is zone
32 central meridian.
+                    case 34: if (λ >= 21) zone++; else zone--; break;   // 21° is zone
34 central meridian.
+                    case 36: if (λ >= 33) zone++; else zone--; break;   // 33° is zone
36 central meridian.
+                }
+                break;
+            }
+        }
+        return zone;
+    }
+
+    /**
+     * Encodes the given position into a MGRS label. It is caller responsibility to ensure
that the
+     * position CRS is the same than the CRS specified at this {@code MGRSEncoder} creation
time.
+     *
+     * @param  position   the direct position to format as a MGRS label.
+     * @param  precision  the precision as a power of 10.
+     * @param  buffer     where to format the direct position.
+     */
+    void encode(DirectPosition position, final double precision, final StringBuilder buffer)
throws TransformException {
+        if (toNormalized != null) {
+            position = toNormalized.transform(position, null);
+        }
+        final DirectPosition geographic;
+        if (crsZone != 0) {
+            geographic = toGeographic.transform(position, null);
+            final double φ = geographic.getOrdinate(1);
+            if (φ >= UTM_SOUTH_BOUNDS && φ <= UTM_NORTH_BOUNDS) {
+                final char   band = latitudeBand(φ);
+                final double    λ = geographic.getOrdinate(0);
+                final int utmZone = TransverseMercator.Zoner.UTM.zone(λ);
+                final int    zone = zone(utmZone, λ, band);
+                if (zone != crsZone) {
+                    // TODO: reproject
+                    throw new IllegalArgumentException();
+                }
+                buffer.append(zone).append(band);
+                /*
+                 * Columns in zone 1 are A-H, zone 2 are J-R (skipping O), zone 3 are S-Z,
+                 * then repeating every 3 zones. The zone number shall not take in account
+                 * the special cases done by the zone(…) method.
+                 */
+                final double x = position.getOrdinate(0);
+                final double y = position.getOrdinate(1);
+                final double cx = Math.floor(x / GRID_SQUARE_SIZE);
+                final double cy = Math.floor(y / GRID_SQUARE_SIZE);
+                int col = (int) cx;
+                if (col < 0 || col >= 8) {
+                    throw new IllegalArgumentException("UTM coordinates out of range"); 
   // TODO: localize
+                }
+                switch (utmZone % 3) {
+                    case 0: col += 'A'; break;
+                    case 1: col += 'J'; if (col >= 'O') col++; break;
+                    case 2: col += 'S'; break;
+                }
+                /*
+                 * Rows in even zones are ABCDEFGHJKLMNPQRSTUV
+                 * Rows in odd  zones are FGHJKLMNPQRSTUVABCDE
+                 * Those 20 letters are repeated in a cycle.
+                 */
+                int row = (int) cy;
+                if ((zone & 1) != 0) {
+                    row += ('F' - 'A');
+                }
+                row = 'A' + (row % 20);
+                if (row >= 'N') row += 2;
+                else if (row >= 'I') row++;
+                buffer.append((char) col).append((char) row);
+                /*
+                 * Numerical location at the given precision.
+                 */
+                final int rx = (int) Math.floor((x - cx * GRID_SQUARE_SIZE) / precision);
+                final int ry = (int) Math.floor((y - cy * GRID_SQUARE_SIZE) / precision);
+            }
+        }
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: 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=1782798&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -0,0 +1,128 @@
+/*
+ * 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.referencing.gazetteer;
+
+import java.util.Map;
+import java.text.ParseException;
+import java.util.IdentityHashMap;
+import java.util.ConcurrentModificationException;
+import org.opengis.util.FactoryException;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.util.ArgumentChecks;
+
+
+/**
+ * The Military Grid Reference System (MGRS).
+ * The MGRS is the geocoordinate standard used by NATO militaries for locating points on
the earth.
+ * It is based on the Universal Transverse Mercator (UTM) and the polar stereographic projections.
+ *
+ * <div class="section">Immutability and thread safety</div>
+ * This class is immutable and thus thread-safe. However the {@code Coder} performing conversions
+ * between labels and coordinates are not thread-safe; a new instance must be created for
each thread.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Military_Grid_Reference_System">Military
Grid Reference System on Wikipedia</a>
+ */
+public class MilitaryGridReferenceSystem {
+    /**
+     * Creates a new Military Grid Reference System (MGRS).
+     */
+    public MilitaryGridReferenceSystem() {
+    }
+
+    /**
+     * Conversions between direct positions and labels in the Military Grid Reference System
(MGRS).
+     * Each {@code Coder} instance can read labels at arbitrary precision, but formats at
the
+     * {@linkplain #setPrecision specified precision}.
+     *
+     * <div class="section">Immutability and thread safety</div>
+     * This class is <strong>not</strong> thread-safe. A new instance must be
created for each thread,
+     * or synchronization must be applied by the caller.
+     *
+     * @author  Martin Desruisseaux (Geomatys)
+     * @since   0.8
+     * @version 0.8
+     * @module
+     */
+    public static class Coder {
+        /**
+         * The precision as a power of 10.
+         */
+        private double precision;
+
+        /**
+         * Cached information needed for building a MGRS label from a direct position in
the given CRS.
+         */
+        private final Map<CoordinateReferenceSystem,MGRSEncoder> encoders;
+
+        /**
+         * A buffer where to create label, to be reused for each new label.
+         */
+        private final StringBuilder buffer;
+
+        /**
+         * Creates a new coder initialized to the default precision.
+         */
+        public Coder() {
+            precision = 1;                          // 1 meter precision.
+            buffer    = new StringBuilder(12);      // Length of "4QFJ12345678" sample value.
+            encoders  = new IdentityHashMap<>();
+        }
+
+        /**
+         * Encodes the given position into a MGRS label.
+         * The given position must have a CRS associated to it.
+         *
+         * @param  position  the coordinate to encode.
+         * @return MGRS encoding of the given position.
+         * @throws TransformException if an error occurred while transforming the given coordinate
to a MGRS label.
+         */
+        public String encode(final DirectPosition position) throws TransformException {
+            ArgumentChecks.ensureNonNull("position", position);
+            final CoordinateReferenceSystem crs = position.getCoordinateReferenceSystem();
+            MGRSEncoder encoder = encoders.get(crs);
+            if (encoder == null) try {
+                encoder = new MGRSEncoder(crs);
+                if (encoders.put(crs, encoder) != null) {
+                    throw new ConcurrentModificationException();            // Opportunistic
check.
+                }
+            } catch (FactoryException e) {
+                throw new TransformException(e.toString(), e);
+            }
+            buffer.setLength(0);
+            encoder.encode(position, precision, buffer);
+            return buffer.toString();
+        }
+
+        /**
+         * Decodes the given MGRS label into a position.
+         *
+         * @param  label  MGRS string to decode.
+         * @return a new position with the longitude at ordinate 0 and latitude at ordinate
1.
+         * @throws ParseException if an error occurred while parsing the given string.
+         */
+        public DirectPosition decode(final String label) throws ParseException {
+            return null;
+        }
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
(from r1782301, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/package-info.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java&p1=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/package-info.java&r1=1782301&r2=1782798&rev=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/package-info.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -17,6 +17,16 @@
 
 
 /**
- * Computes geohash strings from geographic coordinates, and conversely.
+ * Directory mapping geographic identifiers to locations, either as descriptions or coordinates.
+ * Geographic identifiers are location descriptors such as addresses and grid indexes.
+ * Their reference systems are defined by <cite>Spatial referencing by geographic identifiers</cite>
(ISO 19112).
+ * Gazetteers provide linking mechanism between referencing using geographic identifiers
(this package)
+ * and referencing using coordinates ({@link org.apache.sis.referencing.crs} package).
+ *
+ * @author  Chris Mattmann (JPL)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
  */
-package org.apache.sis.index;
+package org.apache.sis.referencing.gazetteer;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -23,7 +23,13 @@
  * <p>The most commonly used kinds of Reference Systems in Apache SIS are the <cite>Coordinate
Reference Systems</cite>
  * (CRS), which handle coordinates of arbitrary dimensions. The SIS implementations can handle
2D and 3D coordinates,
  * as well as 4D, 5D, <i>etc</i>. An other less-frequently used kind of Reference
System uses labels instead, as in
- * postal address. This package is the root for both kinds, with an emphasis on the one for
coordinates.</p>
+ * postal address. This package is the root for both kinds, with an emphasis on the one for
coordinates.
+ * The two kinds of referencing system are implemented in the following packages:</p>
+ * <ul>
+ *   <li>{@link org.apache.sis.referencing.crs} for <cite>referencing by coordinates</cite>
(ISO 19111)</li>
+ *   <li>{@link org.apache.sis.referencing.gazetteer} for <cite>referencing by
geographic identifiers</cite>
+ *       (ISO 19112), together with the linking from geographic identifiers to coordinates.</li>
+ * </ul>
  *
  * <div class="section">Fetching geodetic object instances</div>
  * Geodetic objects can be instantiated either

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java?rev=1782798&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -0,0 +1,60 @@
+/*
+ * 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.referencing.gazetteer;
+
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner.UTM;
+
+
+/**
+ * Tests {@link MGRSEncoder}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public final strictfp class MGRSEncoderTest extends TestCase {
+    /**
+     * Tests {@link MGRSEncoder#latitudeBand(double)}.
+     */
+    @Test
+    public void testLatitudeBand() {
+        assertEquals("80°S", 'C', MGRSEncoder.latitudeBand(-80));
+        assertEquals("55°N", 'U', MGRSEncoder.latitudeBand( 55));
+        assertEquals("56°N", 'V', MGRSEncoder.latitudeBand( 56));
+        assertEquals("63°N", 'V', MGRSEncoder.latitudeBand( 63));
+        assertEquals("64°N", 'W', MGRSEncoder.latitudeBand( 64));
+        assertEquals("71°N", 'W', MGRSEncoder.latitudeBand( 71));
+        assertEquals("72°N", 'X', MGRSEncoder.latitudeBand( 72));
+        assertEquals("84°N", 'X', MGRSEncoder.latitudeBand( 84));
+    }
+
+    /**
+     * Tests {@link MGRSEncoder#zone(double, char)}.
+     */
+    @Test
+    public void testZone() {
+        assertEquals( "4°E band T", 31, MGRSEncoder.zone(UTM.zone( 4), 4, 'T'));
+        assertEquals( "4°E band V", 32, MGRSEncoder.zone(UTM.zone( 4),  4, 'V'));
+        assertEquals("20°E band W", 34, MGRSEncoder.zone(UTM.zone(20), 20, 'W'));
+        assertEquals("20°E band X", 33, MGRSEncoder.zone(UTM.zone(20), 20, 'X'));
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: 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=1782798&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -0,0 +1,53 @@
+/*
+ * 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.referencing.gazetteer;
+
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Tests {@link MilitaryGridReferenceSystem}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+@DependsOn(MGRSEncoderTest.class)
+public final strictfp class MilitaryGridReferenceSystemTest extends TestCase {
+    /**
+     * Tests encoding of coordinates.
+     *
+     * @throws TransformException if an error occurred while computing the MGRS label.
+     */
+    @Test
+    @org.junit.Ignore
+    public void testEncoding() throws TransformException {
+        final MilitaryGridReferenceSystem.Coder coder = new MilitaryGridReferenceSystem.Coder();
+        final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.UTM(13, 103));
+        position.x = 377299;
+        position.y = 1483035;
+        assertEquals("48PUV7729883034", coder.encode(position));
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -244,6 +244,10 @@ import org.junit.BeforeClass;
 
     org.apache.sis.distance.LatLonPointRadiusTest.class,        // Pending refactoring in
a geometry package.
 
+    // Referencing by identifiers
+    org.apache.sis.referencing.gazetteer.MGRSEncoderTest.class,
+    org.apache.sis.referencing.gazetteer.MilitaryGridReferenceSystemTest.class,
+
     org.apache.sis.test.integration.DatumShiftTest.class,
     org.apache.sis.test.integration.MetadataTest.class,
     org.apache.sis.test.integration.ConsistencyTest.class

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -43,6 +43,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Thi Phuong Hao Nguyen (VNSC)
  * @since   0.8
  * @version 0.8
  * @module

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -43,6 +43,7 @@ import org.apache.sis.measure.Units;
  * @author  Rémi Marechal (Geomatys)
  * @author  Alexis Manin (Geomatys)
  * @author  Johann Sorel (Geomatys)
+ * @author  Thi Phuong Hao Nguyen (VNSC)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.8
  * @version 0.8

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/GeoHashCoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/GeoHashCoder.java?rev=1782798&r1=1782797&r2=1782798&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/GeoHashCoder.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/index/GeoHashCoder.java
[UTF-8] Mon Feb 13 16:11:47 2017
@@ -19,7 +19,9 @@ package org.apache.sis.index;
 import java.io.Serializable;
 import java.text.ParseException;
 import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 
@@ -32,7 +34,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Chris Mattmann (JPL)
  * @since   0.1
- * @version 0.3
+ * @version 0.8
  * @module
  *
  * @see <a href="http://en.wikipedia.org/wiki/Geohash">Wikipedia: Geohash</a>
@@ -124,11 +126,18 @@ public class GeoHashCoder implements Ser
     private transient char[] buffer;
 
     /**
+     * The coordinate reference system to assign to the decoded direct positions,
+     * or {@code null} if none.
+     */
+    private final CoordinateReferenceSystem crs;
+
+    /**
      * Creates a new geohash coder/decoder initialized to the default precision for {@link
Format#BASE32}.
      */
     public GeoHashCoder() {
         format = Format.BASE32;
         precision = 12;
+        crs = CommonCRS.defaultGeographic();
     }
 
     /**
@@ -164,7 +173,7 @@ public class GeoHashCoder implements Ser
     /**
      * Sets the length of geohashes strings to be encoded by the {@link #encode(DirectPosition)}
method.
      *
-     * @param  precision  he new length of geohashes strings.
+     * @param  precision  the new length of geohashes strings.
      */
     public void setPrecision(final int precision) {
         ArgumentChecks.ensureBetween("precision", 1, 255, precision);
@@ -250,7 +259,7 @@ public class GeoHashCoder implements Ser
     /**
      * Decodes the given geohash into a longitude and a latitude.
      *
-     * @param geohash Geohash string to decode.
+     * @param  geohash  geohash string to decode.
      * @return a new position with the longitude at ordinate 0 and latitude at ordinate 1.
      * @throws ParseException if an error occurred while parsing the given string.
      */
@@ -307,7 +316,7 @@ public class GeoHashCoder implements Ser
                 isEven = !isEven;
             } while ((mask >>>= 1) != 0);
         }
-        return new DirectPosition2D((xmin + xmax) / 2,
-                                    (ymin + ymax) / 2);
+        return new DirectPosition2D(crs, (xmin + xmax) / 2,
+                                         (ymin + ymax) / 2);
     }
 }



Mime
View raw message