Author: desruisseaux Date: Fri Feb 17 08:50:39 2017 New Revision: 1783350 URL: http://svn.apache.org/viewvc?rev=1783350&view=rev Log: Initial implementation of a CommonCRS.universal(φ,λ) method in replacement of CommonCRS.UTM(φ,λ) for handling the UPS cases. https://issues.apache.org/jira/browse/SIS-353
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java 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/CRS.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -45,6 +45,7 @@ import org.apache.sis.util.ArgumentCheck import org.apache.sis.util.resources.Errors; import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.referencing.provider.TransverseMercator; +import org.apache.sis.internal.referencing.provider.PolarStereographicA; import org.apache.sis.measure.Latitude; import org.apache.sis.referencing.Builder; import org.apache.sis.referencing.CommonCRS; @@ -230,18 +231,22 @@ public class GeodeticObjectBuilder exten * * <blockquote><table class="sis"> * <caption>Transverse Mercator parameters</caption> - * <tr><th>Parameter name</th> <th>Value</th></tr> + * <tr><th>Parameter name</th> <th>Parameter value</th></tr> * <tr><td>Latitude of natural origin</td> <td>Given latitude, snapped to 0° in the UTM case</td></tr> * <tr><td>Longitude of natural origin</td> <td>Given longitude, optionally snapped to a UTM zone</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 in UTM case</td></tr> + * <tr><td>False easting</td> <td>500000 metres in UTM case</td></tr> * <tr><td>False northing</td> <td>0 (North hemisphere) or 10000000 (South hemisphere) metres</td></tr> * </table></blockquote> * * Note that calculation of UTM zone contains special cases for Norway and Svalbard. * If not desired, those exceptions can be avoided by making sure that the given latitude is below 56°N. * - * @param isUTM if {@code true}, the given central meridian will be snapped to the central meridian of a UTM zone. + * <p>If the given {@code zoner} is {@link TransverseMercator.Zoner#ANY ANY}, then this method will use the given + * latitude and longitude verbatim (without snapping them to a zone) but will still use the UTM scale factor, + * false easting and false northing. + * + * @param zoner whether to use UTM or MTM zones, or {@code ANY} for using arbitrary central meridian. * @param latitude the latitude in the center of the desired projection. * @param longitude the longitude in the center of the desired projection. * @return {@code this}, for method calls chaining. @@ -249,13 +254,45 @@ public class GeodeticObjectBuilder exten * * @see CommonCRS#UTM(double, double) */ - public GeodeticObjectBuilder setTransverseMercator(boolean isUTM, double latitude, double longitude) + public GeodeticObjectBuilder setTransverseMercator(TransverseMercator.Zoner zoner, double latitude, double longitude) throws FactoryException { ArgumentChecks.ensureBetween("latitude", Latitude.MIN_VALUE, Latitude.MAX_VALUE, latitude); ArgumentChecks.ensureBetween("longitude", -Formulas.LONGITUDE_MAX, Formulas.LONGITUDE_MAX, longitude); setConversionMethod(TransverseMercator.NAME); - setConversionName(TransverseMercator.Zoner.UTM.setParameters(parameters, isUTM, latitude, longitude)); + setConversionName(zoner.setParameters(parameters, latitude, longitude)); + return this; + } + + /** + * Sets the operation method, parameters and conversion name for a Polar Stereographic projection. + * This convenience method delegates to the following methods: + * + * <ul> + * <li>{@link #setConversionName(String)} with a name like <cite>"Universal Polar Stereographic North"</cite>, + * depending on the argument given to this method.</li> + * <li>{@link #setConversionMethod(String)} with the name of the Polar Stereographic (variant A) projection method.</li> + * <li>{@link #setParameter(String, double, Unit)} for each of the parameters enumerated below:</li> + * </ul> + * + * <blockquote><table class="sis"> + * <caption>Universal Polar Stereographic parameters</caption> + * <tr><th>Parameter name</th> <th>Parameter value</th></tr> + * <tr><td>Latitude of natural origin</td> <td>90°N or 90°S</td></tr> + * <tr><td>Longitude of natural origin</td> <td>0°</td></tr> + * <tr><td>Scale factor at natural origin</td> <td>0.994</td></tr> + * <tr><td>False easting</td> <td>2000000 metres</td></tr> + * <tr><td>False northing</td> <td>2000000 metres</td></tr> + * </table></blockquote> + * + * @param north {@code true} for North pole, or {@code false} for South pole. + * @return {@code this}, for method calls chaining. + * @throws FactoryException if the operation method for the Polar Stereographic (variant A) + * projection can not be obtained. + */ + public GeodeticObjectBuilder setPolarStereographic(final boolean north) throws FactoryException { + setConversionMethod(PolarStereographicA.NAME); + setConversionName(PolarStereographicA.setParameters(parameters, north)); return this; } Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -110,6 +110,36 @@ public final class PolarStereographicA e } /** + * Sets the parameter values for a Universal Polar Stereographic projection + * and returns a suggested conversion name. + * + * <blockquote><table class="sis"> + * <caption>Universal Polar Stereographic parameters</caption> + * <tr><th>Parameter name</th> <th>Value</th></tr> + * <tr><td>Latitude of natural origin</td> <td>90°N or 90°S</td></tr> + * <tr><td>Longitude of natural origin</td> <td>0°</td></tr> + * <tr><td>Scale factor at natural origin</td> <td>0.994</td></tr> + * <tr><td>False easting</td> <td>2000000 metres</td></tr> + * <tr><td>False northing</td> <td>2000000 metres</td></tr> + * </table></blockquote> + * + * @param group the parameters for which to set the values. + * @param north {@code true} for North pole, or {@code false} for South pole. + * @return a name like <cite>"Universal Polar Stereographic North"</cite>, + * depending on the arguments given to this method. + * + * @since 0.8 + */ + public static String setParameters(final ParameterValueGroup group, final boolean north) { + group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(north ? Latitude.MAX_VALUE : Latitude.MIN_VALUE, Units.DEGREE); + group.parameter(Constants.CENTRAL_MERIDIAN) .setValue(0, Units.DEGREE); + group.parameter(Constants.SCALE_FACTOR) .setValue(0.994, Units.UNITY); + group.parameter(Constants.FALSE_EASTING) .setValue(2000000, Units.METRE); + group.parameter(Constants.FALSE_NORTHING) .setValue(2000000, Units.METRE); + return "Universal Polar Stereographic " + (north ? "North" : "South"); + } + + /** * If the given parameter values are those of a Universal Polar Stereographic projection, * returns -1 for South pole or +1 for North pole. Otherwise returns 0. It is caller's * responsibility to verify that the operation method is {@value #NAME}. 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=1783350&r1=1783349&r2=1783350&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] Fri Feb 17 08:50:39 2017 @@ -141,8 +141,8 @@ public final class TransverseMercator ex */ public static enum Zoner { /** - * Computes zones for the Universal Transverse Mercator (UTM) projections. - * This computation includes special cases for Norway and Svalbard. + * Universal Transverse Mercator (UTM) projection zones. + * The zone computation includes special cases for Norway and Svalbard. * * <blockquote><table class="sis"> * <caption>Universal Transverse Mercator parameters</caption> @@ -174,7 +174,7 @@ public final class TransverseMercator ex }, /** - * Computes zones for the Modified Transverse Mercator (MTM) projections. + * Modified Transverse Mercator (MTM) projection zones. * This projection is used in Canada only. * * <blockquote><table class="sis"> @@ -187,7 +187,17 @@ public final class TransverseMercator ex * <tr><td>False northing</td> <td>0 metres</td></tr> * </table></blockquote> */ - MTM(-51.5, -3, 0.9999, 304800, Double.NaN); + MTM(-51.5, -3, 0.9999, 304800, Double.NaN), + + /** + * Like UTM, but allows <cite>latitude of origin</cite> and <cite>central meridian</cite> to be anywhere. + * The given central meridian is not snapped to the UTM zone center and no special case is applied for + * Norway or Svalbard. + * + * <p>This zoner matches the behavior of {@code AUTO(2):42002} authority code specified in the + * OGC <cite>Web Map Service</cite> (WMS) specification.</p> + */ + ANY(Longitude.MIN_VALUE, 6, 0.9996, 500000, 10000000); /** * Longitude of the beginning of zone 1. This is the westmost longitude if {@link #width} is positive, @@ -244,26 +254,28 @@ public final class TransverseMercator ex * </table></blockquote> * * @param group the parameters for which to set the values. - * @param zoned {@code true} for snapping the given latitude/longitude to a zone. * @param latitude the latitude in the center of the desired projection. * @param longitude the longitude in the center of the desired projection. * @return a name like <cite>"Transverse Mercator"</cite> or <cite>"UTM zone 10N"</cite>, * depending on the arguments given to this method. */ - public final String setParameters(final ParameterValueGroup group, - final boolean zoned, double latitude, double longitude) - { + public final String setParameters(final ParameterValueGroup group, double latitude, double longitude) { final boolean isSouth = MathFunctions.isNegative(latitude); int zone = zone(latitude, longitude); - if (zoned) { - latitude = 0; + String name; + if (this == ANY) { + name = "UTM"; + if (latitude != 0 || longitude != centralMeridian(zone)) { + name = NAME; + zone = 0; + } + } else { + name = name(); + latitude = 0; longitude = centralMeridian(zone); - } else if (longitude != centralMeridian(zone)) { - zone = 0; } - String name = NAME; if (zone != 0) { - name = name() + " zone " + zone + (isSouth ? 'S' : 'N'); + name = name + " zone " + zone + (isSouth ? 'S' : 'N'); } group.parameter(Constants.LATITUDE_OF_ORIGIN).setValue(latitude, Units.DEGREE); group.parameter(Constants.CENTRAL_MERIDIAN) .setValue(longitude, Units.DEGREE); @@ -350,5 +362,15 @@ public final class TransverseMercator ex public static boolean isSvalbard(final double φ) { return (φ >= 72) && (φ < 84); } + + /** + * Southernmost bound of the first latitude band ({@code 'C'}), inclusive. + */ + public static final double SOUTH_BOUNDS = -80; + + /** + * Northernmost bound of the last latitude band ({@code 'X'}), exclusive. + */ + public static final double NORTH_BOUNDS = 84; } } Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -145,23 +145,29 @@ public final class CRS extends Static { * * <blockquote><table class="sis"> * <caption>Minimal set of supported authority codes</caption> - * <tr><th>Code</th> <th>Enum</th> <th>CRS Type</th> <th>Description</th></tr> - * <tr><td>CRS:27</td> <td>{@link CommonCRS#NAD27 NAD27}</td> <td>Geographic</td> <td>Like EPSG:4267 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> - * <tr><td>CRS:83</td> <td>{@link CommonCRS#NAD83 NAD83}</td> <td>Geographic</td> <td>Like EPSG:4269 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> - * <tr><td>CRS:84</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic</td> <td>Like EPSG:4326 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> - * <tr><td>EPSG:4047</td> <td>{@link CommonCRS#SPHERE SPHERE}</td> <td>Geographic</td> <td>GRS 1980 Authalic Sphere</td></tr> - * <tr><td>EPSG:4230</td> <td>{@link CommonCRS#ED50 ED50}</td> <td>Geographic</td> <td>European Datum 1950</td></tr> - * <tr><td>EPSG:4258</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geographic</td> <td>European Terrestrial Reference Frame 1989</td></tr> - * <tr><td>EPSG:4267</td> <td>{@link CommonCRS#NAD27 NAD27}</td> <td>Geographic</td> <td>North American Datum 1927</td></tr> - * <tr><td>EPSG:4269</td> <td>{@link CommonCRS#NAD83 NAD83}</td> <td>Geographic</td> <td>North American Datum 1983</td></tr> - * <tr><td>EPSG:4322</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geographic</td> <td>World Geodetic System 1972</td></tr> - * <tr><td>EPSG:4326</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic</td> <td>World Geodetic System 1984</td></tr> - * <tr><td>EPSG:4936</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geocentric</td> <td>European Terrestrial Reference Frame 1989</td></tr> - * <tr><td>EPSG:4937</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geographic 3D</td> <td>European Terrestrial Reference Frame 1989</td></tr> - * <tr><td>EPSG:4978</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geocentric</td> <td>World Geodetic System 1984</td></tr> - * <tr><td>EPSG:4979</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic 3D</td> <td>World Geodetic System 1984</td></tr> - * <tr><td>EPSG:4984</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geocentric</td> <td>World Geodetic System 1972</td></tr> - * <tr><td>EPSG:4985</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geographic 3D</td> <td>World Geodetic System 1972</td></tr> + * <tr><th>Code</th> <th>Enum</th> <th>CRS Type</th> <th>Description</th></tr> + * <tr><td>CRS:27</td> <td>{@link CommonCRS#NAD27 NAD27}</td> <td>Geographic</td> <td>Like EPSG:4267 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> + * <tr><td>CRS:83</td> <td>{@link CommonCRS#NAD83 NAD83}</td> <td>Geographic</td> <td>Like EPSG:4269 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> + * <tr><td>CRS:84</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic</td> <td>Like EPSG:4326 except for (<var>longitude</var>, <var>latitude</var>) axis order</td></tr> + * <tr><td>EPSG:4047</td> <td>{@link CommonCRS#SPHERE SPHERE}</td> <td>Geographic</td> <td>GRS 1980 Authalic Sphere</td></tr> + * <tr><td>EPSG:4230</td> <td>{@link CommonCRS#ED50 ED50}</td> <td>Geographic</td> <td>European Datum 1950</td></tr> + * <tr><td>EPSG:4258</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geographic</td> <td>European Terrestrial Reference Frame 1989</td></tr> + * <tr><td>EPSG:4267</td> <td>{@link CommonCRS#NAD27 NAD27}</td> <td>Geographic</td> <td>North American Datum 1927</td></tr> + * <tr><td>EPSG:4269</td> <td>{@link CommonCRS#NAD83 NAD83}</td> <td>Geographic</td> <td>North American Datum 1983</td></tr> + * <tr><td>EPSG:4322</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geographic</td> <td>World Geodetic System 1972</td></tr> + * <tr><td>EPSG:4326</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic</td> <td>World Geodetic System 1984</td></tr> + * <tr><td>EPSG:4936</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geocentric</td> <td>European Terrestrial Reference Frame 1989</td></tr> + * <tr><td>EPSG:4937</td> <td>{@link CommonCRS#ETRS89 ETRS89}</td> <td>Geographic 3D</td> <td>European Terrestrial Reference Frame 1989</td></tr> + * <tr><td>EPSG:4978</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geocentric</td> <td>World Geodetic System 1984</td></tr> + * <tr><td>EPSG:4979</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Geographic 3D</td> <td>World Geodetic System 1984</td></tr> + * <tr><td>EPSG:4984</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geocentric</td> <td>World Geodetic System 1972</td></tr> + * <tr><td>EPSG:4985</td> <td>{@link CommonCRS#WGS72 WGS72}</td> <td>Geographic 3D</td> <td>World Geodetic System 1972</td></tr> + * <tr><td>EPSG:5041</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Projected</td> <td>WGS 84 / UPS North (E,N)</td></tr> + * <tr><td>EPSG:5042</td> <td>{@link CommonCRS#WGS84 WGS84}</td> <td>Projected</td> <td>WGS 84 / UPS South (E,N)</td></tr> + * <tr><td>EPSG:322##</td><td>{@link CommonCRS#WGS72 WGS72}</td> <td>Projected</td> <td>WGS 72 / UTM zone ##N</td></tr> + * <tr><td>EPSG:323##</td><td>{@link CommonCRS#WGS72 WGS72}</td> <td>Projected</td> <td>WGS 72 / UTM zone ##S</td></tr> + * <tr><td>EPSG:326##</td><td>{@link CommonCRS#WGS84 WGS84}</td> <td>Projected</td> <td>WGS 84 / UTM zone ##N</td></tr> + * <tr><td>EPSG:327##</td><td>{@link CommonCRS#WGS84 WGS84}</td> <td>Projected</td> <td>WGS 84 / UTM zone ##S</td></tr> * <tr><td>EPSG:5715</td> <td>{@link CommonCRS.Vertical#DEPTH DEPTH}</td> <td>Vertical</td> <td>Mean Sea Level depth</td></tr> * <tr><td>EPSG:5714</td> <td>{@link CommonCRS.Vertical#MEAN_SEA_LEVEL MEAN_SEA_LEVEL}</td> <td>Vertical</td> <td>Mean Sea Level height</td></tr> * </table></blockquote> Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -19,7 +19,6 @@ package org.apache.sis.referencing; import java.util.Map; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.logging.Level; import java.util.logging.LogRecord; import javax.measure.Unit; @@ -150,8 +149,8 @@ public enum CommonCRS { * <tr><th>UTM zones:</th> <td>1 to 60 in North and South hemispheres</td></tr> * </table></blockquote> */ - WGS84((short) 4326, (short) 4979, (short) 4978, (short) 6326, (short) 7030, // Geodetic info - (short) 32600, (short) 32700, (byte) 1, (byte) 60), // UTM info + WGS84((short) 4326, (short) 4979, (short) 4978, (short) 6326, (short) 7030, // Geodetic info + (short) 5041, (short) 5042, (short) 32600, (short) 32700, (byte) 1, (byte) 60), // UPS and UTM info /** * World Geodetic System 1972. @@ -168,8 +167,8 @@ public enum CommonCRS { * <tr><th>UTM zones:</th> <td>1 to 60 in North and South hemispheres</td></tr> * </table></blockquote> */ - WGS72((short) 4322, (short) 4985, (short) 4984, (short) 6322, (short) 7043, // Geodetic info - (short) 32200, (short) 32300, (byte) 1, (byte) 60), // UTM info + WGS72((short) 4322, (short) 4985, (short) 4984, (short) 6322, (short) 7043, // Geodetic info + (short) 0, (short) 0, (short) 32200, (short) 32300, (byte) 1, (byte) 60), // UPS and UTM info /** * North American Datum 1983. @@ -194,8 +193,8 @@ public enum CommonCRS { * The <cite>Web Map Server</cite> {@code "CRS:83"} authority code uses the NAD83 datum, * while the {@code "IGNF:MILLER"} authority code uses the GRS80 datum.</div> */ - NAD83((short) 4269, (short) 0, (short) 0, (short) 6269, (short) 7019, // Geodetic info - (short) 26900, (short) 0, (byte) 1, (byte) 23), // UTM info + NAD83((short) 4269, (short) 0, (short) 0, (short) 6269, (short) 7019, // Geodetic info + (short) 0, (short) 0, (short) 26900, (short) 0, (byte) 1, (byte) 23), // UPS and UTM info /** * North American Datum 1927. @@ -212,8 +211,8 @@ public enum CommonCRS { * <tr><th>UTM zones:</th> <td>1 to 22 in the North hemisphere</td></tr> * </table></blockquote> */ - NAD27((short) 4267, (short) 0, (short) 0, (short) 6267, (short) 7008, // Geodetic info - (short) 26700, (short) 0, (byte) 1, (byte) 22), // UTM info + NAD27((short) 4267, (short) 0, (short) 0, (short) 6267, (short) 7008, // Geodetic info + (short) 0, (short) 0, (short) 26700, (short) 0, (byte) 1, (byte) 22), // UPS and UTM info /** * European Terrestrial Reference System 1989. @@ -237,8 +236,8 @@ public enum CommonCRS { * The <cite>Web Map Server</cite> {@code "CRS:83"} authority code uses the NAD83 datum, * while the {@code "IGNF:MILLER"} authority code uses the GRS80 datum.</div> */ - ETRS89((short) 4258, (short) 4937, (short) 4936, (short) 6258, (short) 7019, // Geodetic info - (short) 25800, (short) 0, (byte) 28, (byte) 37), // UTM info + ETRS89((short) 4258, (short) 4937, (short) 4936, (short) 6258, (short) 7019, // Geodetic info + (short) 0, (short) 0, (short) 25800, (short) 0, (byte) 28, (byte) 37), // UPS and UTM info /** * European Datum 1950. @@ -255,8 +254,8 @@ public enum CommonCRS { * <tr><th>UTM zones:</th> <td>28 to 38 in the North hemisphere</td></tr> * </table></blockquote> */ - ED50((short) 4230, (short) 0, (short) 0, (short) 6230, (short) 7022, // Geodetic info - (short) 23000, (short) 0, (byte) 28, (byte) 38), // UTM info + ED50((short) 4230, (short) 0, (short) 0, (short) 6230, (short) 7022, // Geodetic info + (short) 0, (short) 0, (short) 23000, (short) 0, (byte) 28, (byte) 38), // UPS and UTM info /** * Unspecified datum based upon the GRS 1980 Authalic Sphere. Spheres use a simpler algorithm for @@ -274,8 +273,8 @@ public enum CommonCRS { * * @see org.apache.sis.referencing.datum.DefaultEllipsoid#getAuthalicRadius() */ - SPHERE((short) 4047, (short) 0, (short) 0, (short) 6047, (short) 7048, // Geodetic info - (short) 0, (short) 0, (byte) 0, (byte) 0); // UTM info + SPHERE((short) 4047, (short) 0, (short) 0, (short) 6047, (short) 7048, // Geodetic info + (short) 0, (short) 0, (short) 0, (short) 0, (byte) 0, (byte) 0); // UPS and UTM info /** * The enum for the default CRS. @@ -317,6 +316,11 @@ public enum CommonCRS { final short ellipsoid; /** + * EPSG codes of Universal Polar Stereographic projections, North and South cases. + */ + final short northUPS, southUPS; + + /** * EPSG codes of pseudo "UTM zone zero" (North case and South case), or 0 if none. */ final short northUTM, southUTM; @@ -362,12 +366,21 @@ public enum CommonCRS { private transient volatile GeocentricCRS cachedSpherical; /** - * The Universal Transverse Mercator projections, created when first needed. - * All accesses to this map shall be synchronized on {@code cachedUTM}. + * The Universal Transverse Mercator (UTM) or Universal Polar Stereographic (UPS) projections, + * created when first needed. The UPS projections are arbitrarily given zone numbers + * {@value #POLAR} and -{@value #POLAR} for North and South poles respectively. * - * @see #UTM(double, double) + * <p>All accesses to this map shall be synchronized on {@code cachedProjections}.</p> + * + * @see #universal(double, double) + */ + private final Map<Integer,ProjectedCRS> cachedProjections; + + /** + * The special zone number used as key in {@link #cachedProjections} for polar stereographic projections. + * Must be outside the range of UTM zone numbers. */ - private final Map<Integer,ProjectedCRS> cachedUTM; + private static final int POLAR = 90; /** * Creates a new constant for the given EPSG or SIS codes. @@ -379,18 +392,20 @@ public enum CommonCRS { * @param ellipsoid the EPSG code for the ellipsoid. */ private CommonCRS(final short geographic, final short geo3D, final short geocentric, final short datum, final short ellipsoid, - final short northUTM, final short southUTM, final byte firstZone, final byte lastZone) + final short northUPS, final short southUPS, final short northUTM, final short southUTM, final byte firstZone, final byte lastZone) { this.geographic = geographic; this.geocentric = geocentric; this.geo3D = geo3D; this.datum = datum; this.ellipsoid = ellipsoid; + this.northUPS = northUPS; + this.southUPS = southUPS; this.northUTM = northUTM; this.southUTM = southUTM; this.firstZone = firstZone; this.lastZone = lastZone; - cachedUTM = new HashMap<>(); + cachedProjections = new HashMap<>(); } /** @@ -410,14 +425,14 @@ public enum CommonCRS { /** * Invoked by when the cache needs to be cleared after a classpath change. */ - @SuppressWarnings("NestedSynchronizedStatement") // Safe because cachedUTM never call any method of 'this'. + @SuppressWarnings("NestedSynchronizedStatement") // Safe because cachedProjections never call any method of 'this'. synchronized void clear() { cached = null; cachedGeo3D = null; cachedNormalized = null; cachedGeocentric = null; - synchronized (cachedUTM) { - cachedUTM.clear(); + synchronized (cachedProjections) { + cachedProjections.clear(); } } @@ -959,25 +974,50 @@ public enum CommonCRS { /** * Returns a Universal Transverse Mercator (UTM) projection for the zone containing the given point. * There is a total of 120 UTM zones, with 60 zones in the North hemisphere and 60 zones in the South hemisphere. + * + * @param latitude a latitude in the desired UTM projection zone. + * @param longitude a longitude in the desired UTM projection zone. + * @return a Universal Transverse Mercator projection for the zone containing the given point. + * + * @since 0.7 + * + * @deprecated Generalized by {@link #universal(double, double)}, + * which can also return a UPS projection when appropriate. + */ + @Deprecated + public ProjectedCRS UTM(final double latitude, final double longitude) { + return universal(Math.max(-45, Math.min(45, latitude)), longitude); + } + + /** + * Returns a Universal Transverse Mercator (UTM) or a Universal Polar Stereographic (UPS) projection + * for the zone containing the given point. + * There is a total of 120 UTM zones, with 60 zones in the North hemisphere and 60 zones in the South hemisphere. * The projection zone is determined from the arguments as below: * * <ul class="verbose"> - * <li>The sign of the <var>latitude</var> argument determines the hemisphere: - * North for positive latitudes (including positive zero) or - * South for negative latitudes (including negative zero). - * The latitude magnitude is ignored, except for the special cases documented below - * and for ensuring that the latitude is inside the [-90 … 90]° range.</li> - * <li>The value of the <var>longitude</var> argument determines the 6°-width zone, - * numbered from 1 for the zone starting at 180°W up to 60 for the zone finishing at 180°E. - * Longitudes outside the [-180 … 180]° range will be rolled as needed before to compute the zone.</li> - * <li>Calculation of UTM zone involves two special cases (if those special cases are not desired, - * they can be avoided by making sure that the given latitude is below 56°N): - * <ul> - * <li>Between 56°N and 64°N, zone 32 is widened to 9° (at the expense of zone 31) - * to accommodate southwest Norway.</li> - * <li>Between 72°N and 84°N, zones 33 and 35 are 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.</li> + * <li>If the <var>latitude</var> argument is less than 80°S or equal or greater than 84°N, + * then a <cite>Universal Polar Stereographic</cite> projection is created.</li> + * <li>Otherwise a <cite>Universal Transverse Mercator</cite> projection is created as below: + * <ul class="verbose"> + * <li>The sign of the <var>latitude</var> argument determines the hemisphere: + * North for positive latitudes (including positive zero) or + * South for negative latitudes (including negative zero). + * The latitude magnitude is ignored, except for the special cases documented below + * and for ensuring that the latitude is inside the [-90 … 90]° range.</li> + * <li>The value of the <var>longitude</var> argument determines the 6°-width zone, + * numbered from 1 for the zone starting at 180°W up to 60 for the zone finishing at 180°E. + * Longitudes outside the [-180 … 180]° range will be rolled as needed before to compute the zone.</li> + * <li>Calculation of UTM zone involves two special cases (if those special cases are not desired, + * they can be avoided by making sure that the given latitude is below 56°N): + * <ul> + * <li>Between 56°N and 64°N, zone 32 is widened to 9° (at the expense of zone 31) + * to accommodate southwest Norway.</li> + * <li>Between 72°N and 84°N, zones 33 and 35 are 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.</li> + * </ul> + * </li> * </ul> * </li> * </ul> @@ -985,13 +1025,32 @@ public enum CommonCRS { * The map projection uses the following parameters: * * <blockquote><table class="sis"> - * <caption>Universal Transverse Mercator (UTM) parameters</caption> - * <tr><th>Parameter name</th> <th>UTM parameter value</th></tr> - * <tr><td>Latitude of natural origin</td> <td>0°</td></tr> - * <tr><td>Longitude of natural origin</td> <td>Central meridian of the UTM zone containing the given longitude</td></tr> - * <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr> - * <tr><td>False easting</td> <td>500 000 metres</td></tr> - * <tr><td>False northing</td> <td>0 (North hemisphere) or 10 000 000 (South hemisphere) metres</td></tr> + * <caption>Universal Transverse Mercator (UTM) and Universal Polar Stereographic (UPS) projection parameters</caption> + * <tr> + * <th>Parameter name</th> + * <th>UTM parameter value</th> + * <th>UPS parameter value</th> + * </tr><tr> + * <td>Latitude of natural origin</td> + * <td>0°</td> + * <td>90°N or 90°S depending on the sign of given latitude</td> + * </tr><tr> + * <td>Longitude of natural origin</td> + * <td>Central meridian of the UTM zone containing the given longitude</td> + * <td>0°</td> + * </tr><tr> + * <td>Scale factor at natural origin</td> + * <td>0.9996</td> + * <td>0.994</td> + * </tr><tr> + * <td>False easting</td> + * <td>500 000 metres</td> + * <td>2 000 000 metres</td> + * </tr><tr> + * <td>False northing</td> + * <td>0 (North hemisphere) or 10 000 000 (South hemisphere) metres</td> + * <td>2 000 000 metres</td> + * </tr> * </table></blockquote> * * The coordinate system axes are (Easting, Northing) in metres. @@ -1001,59 +1060,83 @@ public enum CommonCRS { * This order is for consistency with the non-normalized {@linkplain #geographic() geographic} CRS * of all items in this {@code CommonCRS} enumeration.</div> * - * @param latitude a latitude in the desired UTM projection zone. - * @param longitude a longitude in the desired UTM projection zone. - * @return a Universal Transverse Mercator projection for the zone containing the given point. + * @param latitude a latitude in the desired UTM or UPS projection zone. + * @param longitude a longitude in the desired UTM or UPS projection zone. + * @return a Universal Transverse Mercator or Polar Stereographic projection for the zone containing the given point. * - * @since 0.7 + * @since 0.8 */ - public ProjectedCRS UTM(final double latitude, final double longitude) { + public ProjectedCRS universal(final double latitude, final double longitude) { ArgumentChecks.ensureBetween("latitude", Latitude.MIN_VALUE, Latitude.MAX_VALUE, latitude); ArgumentChecks.ensureBetween("longitude", -Formulas.LONGITUDE_MAX, Formulas.LONGITUDE_MAX, longitude); final boolean isSouth = MathFunctions.isNegative(latitude); - final int zone = TransverseMercator.Zoner.UTM.zone(latitude, longitude); + final boolean isUTM = latitude >= TransverseMercator.Zoner.SOUTH_BOUNDS + && latitude < TransverseMercator.Zoner.NORTH_BOUNDS; + final int zone = isUTM ? TransverseMercator.Zoner.UTM.zone(latitude, longitude) : POLAR; final Integer key = isSouth ? -zone : zone; ProjectedCRS crs; - synchronized (cachedUTM) { - crs = cachedUTM.get(key); + synchronized (cachedProjections) { + crs = cachedProjections.get(key); } if (crs == null) { + /* + * Requested CRS has not been previously created, or the cache has been cleared. + * Before to create the CRS explicitely, try to get it from the EPSG database. + * Using the EPSG geodetic dataset when possible gives us more information, + * like the aliases and area of validity. + */ int code = 0; - if (zone >= firstZone && zone <= lastZone) { + if (!isUTM) { + code = Short.toUnsignedInt(isSouth ? southUPS : northUPS); + } else if (zone >= firstZone && zone <= lastZone) { code = Short.toUnsignedInt(isSouth ? southUTM : northUTM); - if (code != 0) { - code += zone; - final GeodeticAuthorityFactory factory = factory(); - if (factory != null) try { - return factory.createProjectedCRS(String.valueOf(code)); - } catch (FactoryException e) { - failure(this, "UTM", e, code); - } + } + if (code != 0) { + if (isUTM) code += zone; + final GeodeticAuthorityFactory factory = factory(); + if (factory != null) try { + return factory.createProjectedCRS(String.valueOf(code)); + } catch (FactoryException e) { + failure(this, "universal", e, code); } } /* - * All constants defined in this enumeration use the same coordinate system, EPSG:4400. - * We will arbitrarily create this CS only for a frequently created CRS, and share that - * CS instance for all other constants. + * At this point we couldn't use the EPSG dataset; we have to create the CRS ourselves. + * All constants defined in this enumeration use the same coordinate system (EPSG:4400) + * except for the polar regions. We will arbitrarily create the CS only for a frequently + * used datum, then share that CS instance for all other constants. */ CartesianCS cs = null; - synchronized (DEFAULT.cachedUTM) { - final Iterator<ProjectedCRS> it = DEFAULT.cachedUTM.values().iterator(); - if (it.hasNext()) { - cs = it.next().getCoordinateSystem(); + if (isUTM) { + synchronized (DEFAULT.cachedProjections) { + for (final Map.Entry<Integer,ProjectedCRS> entry : DEFAULT.cachedProjections.entrySet()) { + if (Math.abs(entry.getKey()) != POLAR) { + cs = entry.getValue().getCoordinateSystem(); + break; + } + } } } + /* + * If we didn't found a Coordinate System for EPSG:4400, or if the CS that we needed was + * for another EPSG code (polar cases), delegate to the WGS84 datum or create the CS now. + * + * EPSG:4400 — Cartesian 2D CS. Axes: easting, northing (E,N). Orientations: east, north. UoM: m. + * EPSG:1026 — Cartesian 2D CS for UPS north. Axes: E,N. Orientations: E along 90°E meridian, N along 180°E meridian. UoM: m. + * EPSG:1027 — Cartesian 2D CS for UPS south. Axes: E,N. Orientations: E along 90°E, N along 0°E meridians. UoM: m. + */ if (cs == null) { if (this != DEFAULT) { - cs = DEFAULT.UTM(latitude, longitude).getCoordinateSystem(); + cs = DEFAULT.universal(latitude, longitude).getCoordinateSystem(); } else { - cs = (CartesianCS) StandardDefinitions.createCoordinateSystem(Constants.EPSG_PROJECTED_CS); + cs = (CartesianCS) StandardDefinitions.createCoordinateSystem( + isUTM ? Constants.EPSG_PROJECTED_CS : isSouth ? (short) 1027 : (short) 1026); } } - crs = StandardDefinitions.createUTM(code, geographic(), latitude, longitude, cs); + crs = StandardDefinitions.createUniversal(code, geographic(), isUTM, latitude, longitude, cs); final ProjectedCRS other; - synchronized (cachedUTM) { - other = cachedUTM.putIfAbsent(key, crs); + synchronized (cachedProjections) { + other = cachedProjections.putIfAbsent(key, crs); } if (other != null) { return other; Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -45,6 +45,7 @@ import org.apache.sis.util.resources.Voc import org.apache.sis.util.iso.DefaultNameSpace; import org.apache.sis.util.CharSequences; import org.apache.sis.util.Debug; +import org.apache.sis.measure.Latitude; /** @@ -138,10 +139,14 @@ final class EPSGFactoryFallback extends add(codes, crs.geographic); add(codes, crs.geo3D); } - if (projected && (crs.northUTM != 0 || crs.southUTM != 0)) { - for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) { - if (crs.northUTM != 0) codes.add(Integer.toString(crs.northUTM + zone)); - if (crs.southUTM != 0) codes.add(Integer.toString(crs.southUTM + zone)); + if (projected) { + add(codes, crs.northUPS); + add(codes, crs.southUPS); + if (crs.northUTM != 0 || crs.southUTM != 0) { + for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) { + if (crs.northUTM != 0) codes.add(Integer.toString(crs.northUTM + zone)); + if (crs.southUTM != 0) codes.add(Integer.toString(crs.southUTM + zone)); + } } } } @@ -246,13 +251,19 @@ final class EPSGFactoryFallback extends final double latitude; int zone; if (crs.northUTM != 0 && (zone = n - crs.northUTM) >= crs.firstZone && zone <= crs.lastZone) { - latitude = +1; + latitude = +1; // Any north latitude below 56°N (because of Norway exception) is okay } else if (crs.southUTM != 0 && (zone = n - crs.southUTM) >= crs.firstZone && zone <= crs.lastZone) { - latitude = -1; + latitude = -1; // Any south latitude above 80°S (because of UPS south case) is okay. + } else if (n == crs.northUPS) { + latitude = Latitude.MAX_VALUE; + zone = 30; // Any random UTM zone is okay. + } else if (n == crs.southUPS) { + latitude = Latitude.MIN_VALUE; + zone = 30; // Any random UTM zone is okay. } else { continue; } - return crs.UTM(latitude, TransverseMercator.Zoner.UTM.centralMeridian(zone)); + return crs.universal(latitude, TransverseMercator.Zoner.UTM.centralMeridian(zone)); } } if ((kind & (DATUM | CRS)) != 0) { Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -41,12 +41,14 @@ import org.opengis.util.NoSuchIdentifier import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.metadata.AxisNames; import org.apache.sis.internal.referencing.provider.TransverseMercator; +import org.apache.sis.internal.referencing.provider.PolarStereographicA; import org.apache.sis.metadata.iso.extent.Extents; import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.referencing.datum.DefaultEllipsoid; import org.apache.sis.referencing.datum.DefaultPrimeMeridian; import org.apache.sis.referencing.datum.DefaultGeodeticDatum; import org.apache.sis.referencing.datum.DefaultVerticalDatum; +import org.apache.sis.referencing.cs.CoordinateSystems; import org.apache.sis.referencing.cs.DefaultVerticalCS; import org.apache.sis.referencing.cs.DefaultCartesianCS; import org.apache.sis.referencing.cs.DefaultSphericalCS; @@ -126,29 +128,31 @@ final class StandardDefinitions { } /** - * Returns the operation method for Transverse Mercator projection using the SIS factory implementation. - * This method restricts the factory to SIS implementation instead than arbitrary factory in order to meet - * the contract saying that {@link CommonCRS} methods should never fail. + * Creates a Universal Transverse Mercator (UTM) or a Universal Polar Stereographic (UPS) projected CRS + * using the Apache SIS factory implementation. This method restricts the factory to SIS implementation + * instead than arbitrary factory in order to meet the contract saying that {@link CommonCRS} methods + * should never fail. * * @param code the EPSG code, or 0 if none. * @param baseCRS the geographic CRS on which the projected CRS is based. - * @param latitude a latitude in the zone of the desired projection, to be snapped to 0°. + * @param isUTM {@code true} for UTM or {@code false} for UPS. Note: redundant with the given latitude. + * @param latitude a latitude in the zone of the desired projection, to be snapped to 0°, 90°S or 90°N. * @param longitude a longitude in the zone of the desired projection, to be snapped to UTM central meridian. * @param derivedCS the projected coordinate system. */ - static ProjectedCRS createUTM(final int code, final GeographicCRS baseCRS, + static ProjectedCRS createUniversal(final int code, final GeographicCRS baseCRS, final boolean isUTM, final double latitude, final double longitude, final CartesianCS derivedCS) { final OperationMethod method; try { - method = DefaultFactories.forBuildin(MathTransformFactory.class, - DefaultMathTransformFactory.class) - .getOperationMethod(TransverseMercator.NAME); + method = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class) + .getOperationMethod(isUTM ? TransverseMercator.NAME : PolarStereographicA.NAME); } catch (NoSuchIdentifierException e) { - throw new IllegalStateException(e); // Should not happen with SIS implementation. + throw new IllegalStateException(e); // Should not happen with SIS implementation. } final ParameterValueGroup parameters = method.getParameters().createValue(); - String name = TransverseMercator.Zoner.UTM.setParameters(parameters, true, latitude, longitude); + String name = isUTM ? TransverseMercator.Zoner.UTM.setParameters(parameters, latitude, longitude) + : PolarStereographicA.setParameters(parameters, latitude >= 0); final DefaultConversion conversion = new DefaultConversion(properties(0, name, null, false), method, null, parameters); name = baseCRS.getName().getCode() + " / " + name; @@ -313,16 +317,17 @@ final class StandardDefinitions { @SuppressWarnings("fallthrough") static CoordinateSystem createCoordinateSystem(final short code) { final String name; - final int dim; // Number of dimension. + int type = 0; // 0= Cartesian (default), 1= Spherical, 2= Ellipsoidal + int dim = 2; // Number of dimension, default to 2. short axisCode; // Code of first axis + dim (or code after the last axis). - boolean isCartesian = false; - boolean isSpherical = false; switch (code) { - case 6422: name = "Ellipsoidal 2D"; dim = 2; axisCode = 108; break; - case 6423: name = "Ellipsoidal 3D"; dim = 3; axisCode = 111; break; - case 6404: name = "Spherical"; dim = 3; axisCode = 63; isSpherical = true; break; - case 6500: name = "Earth centred"; dim = 3; axisCode = 118; isCartesian = true; break; - case 4400: name = "Cartesian 2D"; dim = 2; axisCode = 3; isCartesian = true; break; + case 6422: name = "Ellipsoidal 2D"; type = 2; axisCode = 108; break; + case 6423: name = "Ellipsoidal 3D"; type = 2; dim = 3; axisCode = 111; break; + case 6404: name = "Spherical"; type = 1; dim = 3; axisCode = 63; break; + case 6500: name = "Earth centred"; dim = 3; axisCode = 118; break; + case 4400: name = "Cartesian 2D"; axisCode = 3; break; + case 1026: name = "Cartesian 2D for UPS north"; axisCode = 1067; break; + case 1027: name = "Cartesian 2D for UPS south"; axisCode = 1059; break; default: throw new AssertionError(code); } final Map<String,?> properties = properties(code, name, null, false); @@ -334,20 +339,13 @@ final class StandardDefinitions { case 1: xAxis = createAxis(--axisCode); case 0: break; } - if (isCartesian) { - if (zAxis != null) { - return new DefaultCartesianCS(properties, xAxis, yAxis, zAxis); - } else { - return new DefaultCartesianCS(properties, xAxis, yAxis); - } - } else if (isSpherical) { - return new DefaultSphericalCS(properties, xAxis, yAxis, zAxis); - } else { - if (zAxis != null) { - return new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis); - } else { - return new DefaultEllipsoidalCS(properties, xAxis, yAxis); - } + switch (type) { + default: throw new AssertionError(type); + case 0: return (zAxis != null) ? new DefaultCartesianCS (properties, xAxis, yAxis, zAxis) + : new DefaultCartesianCS (properties, xAxis, yAxis); + case 1: return new DefaultSphericalCS (properties, xAxis, yAxis, zAxis); + case 2: return (zAxis != null) ? new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis) + : new DefaultEllipsoidalCS(properties, xAxis, yAxis); } } @@ -367,12 +365,10 @@ final class StandardDefinitions { switch (code) { case 1: name = "Easting"; abrv = "E"; - unit = Units.METRE; dir = AxisDirection.EAST; break; case 2: name = "Northing"; abrv = "N"; - unit = Units.METRE; dir = AxisDirection.NORTH; break; case 60: name = "Spherical latitude"; @@ -393,7 +389,6 @@ final class StandardDefinitions { break; case 62: name = "Geocentric radius"; abrv = "R"; // See HardCodedAxes.GEOCENTRIC_RADIUS in tests. - unit = Units.METRE; dir = AxisDirection.UP; rm = RangeMeaning.EXACT; min = 0; @@ -440,6 +435,23 @@ final class StandardDefinitions { abrv = "Z"; dir = AxisDirection.GEOCENTRIC_Z; break; + case 1057: // Actually no axis allocated by EPSG here, but createCoordinateSystem(1027) needs this number. + case 1056: name = "Easting"; + abrv = "E"; + dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 90); + break; + case 1058: name = "Northing"; + abrv = "N"; + dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 0); + break; + case 1065: name = "Easting"; + abrv = "E"; + dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 90); + break; + case 1066: name = "Northing"; + abrv = "N"; + dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 180); + break; default: throw new AssertionError(code); } final Map<String,Object> properties = properties(code, name, null, false); Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -43,6 +43,7 @@ import org.opengis.referencing.cs.Cartes import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.datum.DatumFactory; import org.opengis.referencing.datum.EngineeringDatum; +import org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner; import org.apache.sis.internal.referencing.GeodeticObjectBuilder; import org.apache.sis.internal.referencing.Resources; import org.apache.sis.metadata.iso.citation.Citations; @@ -60,8 +61,6 @@ import org.apache.sis.util.resources.Err import org.apache.sis.util.iso.DefaultNameSpace; import org.apache.sis.util.iso.SimpleInternationalString; -import static org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner.UTM; - /** * Creates coordinate reference systems in the "{@code OGC}", "{@code CRS}" or {@code "AUTO(2)"} namespaces. @@ -587,7 +586,7 @@ public class CommonAuthorityFactory exte * 42005: WGS 84 / Auto Mollweide — defined by "Central_Meridian" only. */ case 42001: isUTM = true; break; - case 42002: isUTM = (latitude == 0) && (UTM.centralMeridian(UTM.zone(0, longitude)) == longitude); break; + case 42002: isUTM = (latitude == 0) && (Zoner.UTM.centralMeridian(Zoner.UTM.zone(0, longitude)) == longitude); break; case 42003: method = "Orthographic"; param = Constants.LATITUDE_OF_ORIGIN; break; case 42004: method = "Equirectangular"; param = Constants.STANDARD_PARALLEL_1; break; case 42005: method = "Mollweide"; break; @@ -598,9 +597,9 @@ public class CommonAuthorityFactory exte * enumeration if possible because CommonCRS will itself delegate to the EPSG factory if possible. */ final CommonCRS datum = CommonCRS.WGS84; - final GeographicCRS baseCRS; - final ProjectedCRS crs; - CartesianCS cs; + final GeographicCRS baseCRS; // To be set, directly or indirectly, to WGS84.geographic(). + final ProjectedCRS crs; // Temporary UTM projection, for extracting other properties. + CartesianCS cs; // Coordinate system with (E,N) axes in metres. try { if (isUTM != null && isUTM) { crs = datum.UTM(latitude, longitude); @@ -640,10 +639,10 @@ public class CommonAuthorityFactory exte */ final GeodeticObjectBuilder builder = new GeodeticObjectBuilder(); if (isUTM != null) { - if (isUTM) { + if (isUTM && crs != null) { builder.addName(crs.getName()); } // else default to the conversion name, which is "Transverse Mercator". - builder.setTransverseMercator(isUTM, latitude, longitude); + builder.setTransverseMercator(isUTM ? Zoner.UTM : Zoner.ANY, latitude, longitude); } else { builder.setConversionMethod(method) .addName(PROJECTION_NAMES[projection - FIRST_PROJECTION_CODE]) 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=1783350&r1=1783349&r2=1783350&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] Fri Feb 17 08:50:39 2017 @@ -61,16 +61,6 @@ final class MGRSEncoder { private static final double LATITUDE_BAND_HEIGHT = 8; /** - * Southernmost bound of the first latitude band ({@code 'C'}). - */ - static final double UTM_SOUTH_BOUNDS = -80; - - /** - * Northernmost bound of the last latitude band ({@code 'X'}). - */ - static final double UTM_NORTH_BOUNDS = 84; - - /** * Special {@link #crsZone} value for the UPS South (Universal Polar Stereographic) projection. */ private static final int SOUTH_POLE = -1000; @@ -244,7 +234,7 @@ final class MGRSEncoder { * @return the band letter for the given latitude. */ static char latitudeBand(final double φ) { - int band = 'C' + (int) ((φ - UTM_SOUTH_BOUNDS) / LATITUDE_BAND_HEIGHT); + int band = 'C' + (int) ((φ - TransverseMercator.Zoner.SOUTH_BOUNDS) / LATITUDE_BAND_HEIGHT); if (band >= EXCLUDE_I && ++band >= EXCLUDE_O && ++band == 'Y') { band = 'X'; // Because the last latitude band ('X') is 12° height instead of 8°. } @@ -272,7 +262,9 @@ final class MGRSEncoder { final DirectPosition geographic = toGeographic.transform(position, owner.geographic); owner.geographic = geographic; // For reuse in next method calls. final double φ = geographic.getOrdinate(0); - if (φ >= UTM_SOUTH_BOUNDS && φ <= UTM_NORTH_BOUNDS) { + if (φ >= TransverseMercator.Zoner.SOUTH_BOUNDS && + φ < TransverseMercator.Zoner.NORTH_BOUNDS) + { /* * Universal Transverse Mercator (UTM) case. */ @@ -286,7 +278,7 @@ final class MGRSEncoder { if (sz != crsZone) { if (sz != actualZone) { actualZone = 0; // In case an exception is thrown on the next line. - toActualZone = CRS.findOperation(datum.geographic(), datum.UTM(φ, λ), null).getMathTransform(); + toActualZone = CRS.findOperation(datum.geographic(), datum.universal(φ, λ), null).getMathTransform(); actualZone = sz; } owner.normalized = position = toActualZone.transform(geographic, owner.normalized); Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -90,7 +90,7 @@ public abstract strictfp class Transform */ @Test public final void testTransform() throws FactoryException, TransformException { - final ProjectedCRS targetCRS = CommonCRS.WGS84.UTM(10, -123.5); + final ProjectedCRS targetCRS = CommonCRS.WGS84.universal(10, -123.5); final GeographicCRS sourceCRS = targetCRS.getBaseCRS(); final Conversion conversion = targetCRS.getConversionFromBase(); final MathTransform2D transform = (MathTransform2D) conversion.getMathTransform(); @@ -199,7 +199,7 @@ public abstract strictfp class Transform @Test @DependsOnMethod("testTransform") public final void testTransformNotOverPole() throws FactoryException, TransformException { - final ProjectedCRS sourceCRS = CommonCRS.WGS84.UTM(10, -3.5); + final ProjectedCRS sourceCRS = CommonCRS.WGS84.universal(10, -3.5); final GeographicCRS targetCRS = sourceCRS.getBaseCRS(); final Conversion conversion = inverse(sourceCRS.getConversionFromBase()); final G rectangle = createFromExtremums(sourceCRS, 199980, 4490220, 309780, 4600020); Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/TransverseMercatorTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -62,7 +62,7 @@ public final strictfp class TransverseMe } /** - * Tests {@link TransverseMercator.Zoner#setParameters(ParameterValueGroup, boolean, double, double)} + * Tests {@link TransverseMercator.Zoner#setParameters(ParameterValueGroup, double, double)} * followed by {@link TransverseMercator.Zoner#zone(ParameterValueGroup)}. */ @Test @@ -72,17 +72,17 @@ public final strictfp class TransverseMe }) public void testSetParameters() { final ParameterValueGroup p = TransverseMercator.PARAMETERS.createValue(); - assertEquals("UTM zone 10N", TransverseMercator.Zoner.UTM.setParameters(p, true, 0, -122)); + assertEquals("UTM zone 10N", TransverseMercator.Zoner.UTM.setParameters(p, 0, -122)); assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT); assertEquals(Constants.FALSE_NORTHING, 0, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT); assertEquals("UTM.zone(parameters)", 10, TransverseMercator.Zoner.UTM.zone(p)); - assertEquals("Transverse Mercator", TransverseMercator.Zoner.UTM.setParameters(p, false, 0, -122)); + assertEquals("Transverse Mercator", TransverseMercator.Zoner.ANY.setParameters(p, 0, -122)); assertEquals(Constants.CENTRAL_MERIDIAN, -122, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT); assertEquals(Constants.FALSE_NORTHING, 0, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT); assertEquals("UTM.zone(parameters)", 0, TransverseMercator.Zoner.UTM.zone(p)); - assertEquals("UTM zone 10S", TransverseMercator.Zoner.UTM.setParameters(p, false, -0.0, -123)); + assertEquals("UTM zone 10S", TransverseMercator.Zoner.ANY.setParameters(p, -0.0, -123)); assertEquals(Constants.CENTRAL_MERIDIAN, -123, p.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT); assertEquals(Constants.FALSE_NORTHING, 10000000, p.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT); assertEquals("UTM.zone(parameters)", -10, TransverseMercator.Zoner.UTM.zone(p)); Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CommonCRSTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -79,6 +79,8 @@ public final strictfp class CommonCRSTes assertNoCodeCollision(codes, crs, crs.geographic); assertNoCodeCollision(codes, crs, crs.geocentric); assertNoCodeCollision(codes, crs, crs.geo3D); + assertNoCodeCollision(codes, crs, crs.northUPS); + assertNoCodeCollision(codes, crs, crs.southUPS); for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) { if (crs.northUTM != 0) assertNoCodeCollision(codes, crs, crs.northUTM + zone); if (crs.southUTM != 0) assertNoCodeCollision(codes, crs, crs.southUTM + zone); @@ -276,20 +278,41 @@ public final strictfp class CommonCRSTes } /** - * Tests {@link CommonCRS#UTM(double, double)}. + * Tests {@link CommonCRS#universal(double, double)} with Universal Transverse Mercator (UTM) projections. * * @since 0.7 */ @Test @DependsOnMethod("testGeographic") public void testUTM() { - final ProjectedCRS crs = CommonCRS.WGS72.UTM(-45, -122); + final ProjectedCRS crs = CommonCRS.WGS72.universal(-45, -122); assertEquals("name", "WGS 72 / UTM zone 10S", crs.getName().getCode()); final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues(); - assertEquals(Constants.LATITUDE_OF_ORIGIN, -123, pg.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT); - assertEquals(Constants.FALSE_NORTHING, 10000000, pg.parameter(Constants.FALSE_NORTHING).doubleValue(), STRICT); - assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.UTM(-45, -122)); - assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.UTM(+45, -122)); + assertEquals(Constants.LATITUDE_OF_ORIGIN, 0, pg.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(), STRICT); + assertEquals(Constants.CENTRAL_MERIDIAN, -123, pg.parameter(Constants.CENTRAL_MERIDIAN) .doubleValue(), STRICT); + assertEquals(Constants.FALSE_EASTING, 500000, pg.parameter(Constants.FALSE_EASTING) .doubleValue(), STRICT); + assertEquals(Constants.FALSE_NORTHING, 10000000, pg.parameter(Constants.FALSE_NORTHING) .doubleValue(), STRICT); + assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.universal(-45, -122)); + assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.universal(+45, -122)); + } + + /** + * Tests {@link CommonCRS#universal(double, double)} with Universal Polar Stereographic (UPS) projections. + * + * @since 0.8 + */ + @Test + @DependsOnMethod("testGeographic") + public void testUPS() { + final ProjectedCRS crs = CommonCRS.WGS72.universal(-85, -122); + assertEquals("name", "WGS 72 / Universal Polar Stereographic South", crs.getName().getCode()); + final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues(); + assertEquals(Constants.LATITUDE_OF_ORIGIN, -90, pg.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(), STRICT); + assertEquals(Constants.CENTRAL_MERIDIAN, 0, pg.parameter(Constants.CENTRAL_MERIDIAN) .doubleValue(), STRICT); + assertEquals(Constants.FALSE_EASTING, 2000000, pg.parameter(Constants.FALSE_EASTING) .doubleValue(), STRICT); + assertEquals(Constants.FALSE_NORTHING, 2000000, pg.parameter(Constants.FALSE_NORTHING) .doubleValue(), STRICT); + assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.universal(-85, -122)); + assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.universal(+85, -122)); } /** Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -71,14 +71,15 @@ public final strictfp class StandardDefi } /** - * Tests {@link StandardDefinitions#createUTM(int, GeographicCRS, double, boolean, CartesianCS)}. + * Tests {@link StandardDefinitions#createUniversal(int, GeographicCRS, boolean, double, double, CartesianCS)} + * for a Universal Transverse Mercator (UTM) projection. * * @since 0.7 */ @Test @DependsOnMethod("testCreateGeographicCRS") public void testCreateUTM() { - final ProjectedCRS crs = StandardDefinitions.createUTM(32610, HardCodedCRS.WGS84, 15, -122, HardCodedCS.PROJECTED); + final ProjectedCRS crs = StandardDefinitions.createUniversal(32610, HardCodedCRS.WGS84, true, 15, -122, HardCodedCS.PROJECTED); assertEquals("name", "WGS 84 / UTM zone 10N", crs.getName().getCode()); final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues(); assertEquals(Constants.LATITUDE_OF_ORIGIN, -123, pg.parameter(Constants.CENTRAL_MERIDIAN).doubleValue(), STRICT); Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -209,7 +209,7 @@ public final strictfp class EPSGInstalle * This implies the creation of a coordinate operation. */ final ProjectedCRS p = factory.createProjectedCRS("EPSG:32215"); - assertTrue(Utilities.deepEquals(CommonCRS.WGS72.UTM(1, -93), p, ComparisonMode.DEBUG)); + assertTrue(Utilities.deepEquals(CommonCRS.WGS72.universal(1, -93), p, ComparisonMode.DEBUG)); /* * Get the authority codes. We choose a type that implies an SQL statement * with both "DEPRECATED" and "SHOW_CRS" conditions in their "WHERE" clause. Modified: 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=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -64,7 +64,7 @@ public final strictfp class MGRSEncoderT */ @Test public void verifyZonerConsistency() { - for (double φ = MGRSEncoder.UTM_SOUTH_BOUNDS; φ < MGRSEncoder.UTM_NORTH_BOUNDS; φ++) { + for (double φ = Zoner.SOUTH_BOUNDS; φ < Zoner.NORTH_BOUNDS; φ++) { final String latitude = String.valueOf(φ); final char band = MGRSEncoder.latitudeBand(φ); assertTrue (latitude, band >= 'C' && band <= 'X'); 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=1783350&r1=1783349&r2=1783350&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] Fri Feb 17 08:50:39 2017 @@ -56,21 +56,21 @@ public final strictfp class MilitaryGrid /* * 41°N 10°E (UTM zone 32) */ - position.setCoordinateReferenceSystem(CommonCRS.WGS84.UTM(41, 10)); + position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(41, 10)); position.x = 584102; position.y = 4539239; assertEquals("32TNL8410239239", coder.encode(position)); /* * 82°N 10°W (UTM zone 29) — should instantiate a new MGRSEncoder. */ - position.setCoordinateReferenceSystem(CommonCRS.WGS84.UTM(82, -10)); + position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(82, -10)); position.x = 484463; position.y = 9104963; assertEquals("29XMM8446304963", coder.encode(position)); /* * 41°S 10°E (UTM zone 32) — should reuse the MGRSEncoder created in first test. */ - position.setCoordinateReferenceSystem(CommonCRS.WGS84.UTM(-41, 10)); + position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(-41, 10)); position.x = 584102; position.y = 5460761; assertEquals("32GNV8410260761", coder.encode(position)); @@ -78,7 +78,7 @@ public final strictfp class MilitaryGrid * 82°N 10°E (UTM zone 32) — in this special case, zone 32 is replaced by zone 33. * Call to WGS84.UTM(φ,λ) needs to specify a smaller latitude for getting zone 32. */ - position.setCoordinateReferenceSystem(CommonCRS.WGS84.UTM(40, 10)); + position.setCoordinateReferenceSystem(CommonCRS.WGS84.universal(40, 10)); position.x = 515537; position.y = 9104963; assertEquals("33XVM2240708183", coder.encode(position)); @@ -103,7 +103,7 @@ public final strictfp class MilitaryGrid @DependsOnMethod("testEncoding") public void testPrecision() throws TransformException { final MilitaryGridReferenceSystem.Coder coder = coder(); - final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.UTM(13, 103)); + final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.universal(13, 103)); position.x = 377299; position.y = 1483035; assertEquals("precision", 1, coder.getPrecision(), STRICT); @@ -137,7 +137,7 @@ public final strictfp class MilitaryGrid @DependsOnMethod("testPrecision") public void testSeparator() throws TransformException { final MilitaryGridReferenceSystem.Coder coder = coder(); - final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.UTM(13, 103)); + final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.universal(13, 103)); position.x = 377299; position.y = 1483035; assertEquals("separator", "", coder.getSeparator()); Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -175,7 +175,7 @@ public final strictfp class CoordinateOp testIdentityTransform(CommonCRS.WGS84.geographic3D()); testIdentityTransform(CommonCRS.WGS84.geocentric()); testIdentityTransform(CommonCRS.WGS84.spherical()); - testIdentityTransform(CommonCRS.WGS84.UTM(0, 0)); + testIdentityTransform(CommonCRS.WGS84.universal(0, 0)); testIdentityTransform(CommonCRS.Vertical.DEPTH.crs()); testIdentityTransform(CommonCRS.Temporal.JULIAN.crs()); } Modified: sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java?rev=1783350&r1=1783349&r2=1783350&view=diff ============================================================================== --- sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] (original) +++ sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] Fri Feb 17 08:50:39 2017 @@ -904,7 +904,7 @@ final class LandsatReader { */ if (datum != null) { if (utmZone > 0) { - metadata.add(datum.UTM(1, TransverseMercator.Zoner.UTM.centralMeridian(utmZone))); + metadata.add(datum.universal(1, TransverseMercator.Zoner.UTM.centralMeridian(utmZone))); } if (projection != null) { final double sp = projection.parameter(Constants.STANDARD_PARALLEL_1).doubleValue();