You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/09/09 16:43:51 UTC
svn commit: r1702031 - in /sis/trunk: ./
core/sis-metadata/src/main/java/org/apache/sis/io/wkt/
core/sis-metadata/src/test/java/org/apache/sis/io/wkt/
core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/
core/sis-referencing...
Author: desruisseaux
Date: Wed Sep 9 14:43:51 2015
New Revision: 1702031
URL: http://svn.apache.org/r1702031
Log:
Merge from the JDK6 branch.
Modified:
sis/trunk/ (props changed)
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Colors.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ColorsTest.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MercatorSpherical.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedName.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java
Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 9 14:43:51 2015
@@ -1,4 +1,4 @@
/sis/branches/Android:1430670-1480699
-/sis/branches/JDK6:1394364-1701642
-/sis/branches/JDK7:1394913-1701639
-/sis/branches/JDK8:1584960-1701637
+/sis/branches/JDK6:1394364-1702026
+/sis/branches/JDK7:1394913-1702025
+/sis/branches/JDK8:1584960-1702023
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Colors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Colors.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Colors.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Colors.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -65,7 +65,8 @@ public class Colors implements Cloneable
map.put(ElementKind.CODE_LIST, X364.FOREGROUND_CYAN);
map.put(ElementKind.PARAMETER, X364.FOREGROUND_GREEN);
map.put(ElementKind.METHOD, X364.FOREGROUND_GREEN);
- map.put(ElementKind.DATUM, X364.FOREGROUND_GREEN);
+ map.put(ElementKind.DATUM, X364.FOREGROUND_BLUE); // Because datum names in SIS are like identifiers.
+ map.put(ElementKind.IDENTIFIER, X364.FOREGROUND_BLUE);
map.put(ElementKind.SCOPE, X364.FOREGROUND_GRAY);
map.put(ElementKind.EXTENT, X364.FOREGROUND_GRAY);
map.put(ElementKind.CITATION, X364.FOREGROUND_GRAY);
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -761,6 +761,7 @@ public class Formatter implements Locali
appendForSubtypes(object);
}
if (showIDs) {
+ @SuppressWarnings("null")
Collection<ReferenceIdentifier> identifiers = object.getIdentifiers();
if (identifiers != null) { // Paranoiac check
if (filterID) {
@@ -1112,7 +1113,11 @@ public class Formatter implements Locali
*/
public void append(final long number) {
appendSeparator();
- setColor(ElementKind.INTEGER);
+ /*
+ * The check for 'isComplement' is a hack for ImmutableIdentifier.formatTo(Formatter).
+ * We do not have a public API for controlling the integer colors (it may not be desirable).
+ */
+ setColor(isComplement ? ElementKind.IDENTIFIER : ElementKind.INTEGER);
numberFormat.setMaximumFractionDigits(0);
numberFormat.format(number, buffer, dummy);
resetColor();
Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ColorsTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ColorsTest.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ColorsTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ColorsTest.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -39,7 +39,8 @@ public final strictfp class ColorsTest e
public void testGetName() {
final Colors colors = Colors.DEFAULT;
assertEquals("cyan", colors.getName(ElementKind.CODE_LIST));
- assertEquals("green", colors.getName(ElementKind.DATUM));
+ assertEquals("green", colors.getName(ElementKind.METHOD));
+ assertEquals("blue", colors.getName(ElementKind.DATUM));
assertEquals("red", colors.getName(ElementKind.ERROR));
}
@@ -50,9 +51,9 @@ public final strictfp class ColorsTest e
@DependsOnMethod("testGetName")
public void testSetName() {
final Colors colors = new Colors(Colors.DEFAULT);
- assertEquals("green", colors.getName(ElementKind.DATUM));
- colors.setName(ElementKind.DATUM, "blue");
- assertEquals("blue", colors.getName(ElementKind.DATUM));
+ assertEquals("green", colors.getName(ElementKind.METHOD));
+ colors.setName(ElementKind.METHOD, "blue");
+ assertEquals("blue", colors.getName(ElementKind.METHOD));
}
/**
@@ -61,7 +62,7 @@ public final strictfp class ColorsTest e
@Test
public void testImmutability() {
try {
- Colors.DEFAULT.setName(ElementKind.DATUM, "blue");
+ Colors.DEFAULT.setName(ElementKind.METHOD, "blue");
fail("Constant shall be immutable.");
} catch (UnsupportedOperationException e) {
// This is the expected exception.
@@ -77,9 +78,9 @@ public final strictfp class ColorsTest e
public void testSerialization() {
assertSame(Colors.DEFAULT, assertSerializedEquals(Colors.DEFAULT));
final Colors colors = new Colors(Colors.DEFAULT);
- colors.setName(ElementKind.DATUM, "blue");
+ colors.setName(ElementKind.METHOD, "blue");
final Colors c = assertSerializedEquals(colors);
assertNotSame(colors, c); // Expect a new instance.
- assertEquals("blue", c.getName(ElementKind.DATUM));
+ assertEquals("blue", c.getName(ElementKind.METHOD));
}
}
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -35,6 +35,7 @@ import org.apache.sis.metadata.iso.citat
import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.referencing.operation.DefaultOperationMethod;
import org.apache.sis.referencing.operation.transform.MathTransformProvider;
+import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.Workaround;
@@ -114,6 +115,26 @@ abstract class AbstractProvider extends
}
/**
+ * Adds a name together with its previous (legacy) name.
+ * The legacy name will be added as a deprecated alias.
+ */
+ static ParameterBuilder addNameAndLegacy(final ParameterBuilder builder, final String name, final String legacy) {
+ return builder.addName(name).setDeprecated(true)
+ .setRemarks(Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, name))
+ .addName(legacy).setDeprecated(false).setRemarks(null);
+ }
+
+ /**
+ * Adds an identifier code together with its previous (legacy) code.
+ * The legacy code will be added as a deprecated identifier.
+ */
+ static ParameterBuilder addIdentifierAndLegacy(final ParameterBuilder builder, final String code, final String legacy) {
+ return builder.addIdentifier(code).setDeprecated(true)
+ .setRemarks(Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, code))
+ .addIdentifier(legacy).setDeprecated(false).setRemarks(null);
+ }
+
+ /**
* Creates a descriptor for a 0 constant value in degrees.
*
* @see MapProjection#validate(ParameterDescriptor, double)
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Equirectangular.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -176,9 +176,7 @@ public final class Equirectangular exten
// Do not declare the ESRI "Equidistant_Cylindrical" projection name below,
// for avoiding confusion with EPSG "Equidistant Cylindrical" ellipsoidal projection.
- PARAMETERS = builder
- .addIdentifier( "1029")
- .addDeprecatedIdentifier( "9823", "1029") // Using deprecated parameter names
+ PARAMETERS = addIdentifierAndLegacy(builder, "1029", "9823") // 9823 uses deprecated parameter names
.addName( "Equidistant Cylindrical (Spherical)")
.addName( "Plate Carrée") // Not formally defined by EPSG, but cited in documentation.
.addName(Citations.OGC, "Equirectangular")
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -91,7 +91,7 @@ public final class Mercator2SP extends A
.rename(Citations.GEOTIFF, (String[]) null) // "ScaleAtNatOrigin" is too specific.
.setRemarks(remarks).setDeprecated(true));
- PARAMETERS = builder.setDeprecated(false)
+ PARAMETERS = builder
.addIdentifier( "9805")
.addName( "Mercator (variant B)") // Starting from EPSG version 7.6
.addName( "Mercator (2SP)") // Prior to EPSG version 7.6
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MercatorSpherical.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MercatorSpherical.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MercatorSpherical.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MercatorSpherical.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -62,11 +62,8 @@ public final class MercatorSpherical ext
.setRemarks(Mercator2SP.SCALE_FACTOR.getRemarks())
.setRequired(false));
- PARAMETERS = builder
- .addIdentifier(IDENTIFIER)
- .addDeprecatedIdentifier("9841", IDENTIFIER)
- .addName("Mercator (Spherical)") // Starting from EPSG version 7.6
- .addDeprecatedName("Mercator (1SP) (Spherical)", "Mercator (Spherical)") // Prior to EPSG version 7.6
+ PARAMETERS = addNameAndLegacy(addIdentifierAndLegacy(builder, IDENTIFIER, "9841"),
+ "Mercator (Spherical)", "Mercator (1SP) (Spherical)") // "Mercator (Spherical)" starting from EPSG version 7.6
.createGroupForMapProjection(
Mercator1SP.LATITUDE_OF_ORIGIN,
Mercator1SP.LONGITUDE_OF_ORIGIN,
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -76,7 +76,7 @@ public final class PolarStereographicB e
final ParameterBuilder builder = builder();
LONGITUDE_OF_ORIGIN = createLongitude(
exceptEPSG(PolarStereographicA.LONGITUDE_OF_ORIGIN,
- builder.addIdentifier("8833").addName("Longitude of origin").setDeprecated(false)));
+ builder.addIdentifier("8833").addName("Longitude of origin")));
STANDARD_PARALLEL = createMandatoryLatitude(builder
.addIdentifier("8832").addName("Latitude of standard parallel")
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -166,6 +166,18 @@ public class ParameterBuilder extends Bu
}
/**
+ * Creates a descriptor for values of the given type without domain restriction.
+ *
+ * @param <T> The compile-time type of the {@code valueClass} argument.
+ * @param valueClass The class that describe the type of the parameter values.
+ * @param defaultValue The default value for the parameter, or {@code null} if none.
+ * @return The parameter descriptor for the given default value and unit.
+ */
+ public <T> ParameterDescriptor<T> create(final Class<T> valueClass, final T defaultValue) {
+ return create(valueClass, null, null, defaultValue);
+ }
+
+ /**
* Creates a descriptor for floating point values without domain restriction.
* All {@code double} values are considered valid.
*
@@ -184,18 +196,6 @@ public class ParameterBuilder extends Bu
}
/**
- * Creates a descriptor for values of the given type without domain restriction.
- *
- * @param <T> The compile-time type of the {@code valueClass} argument.
- * @param valueClass The class that describe the type of the parameter values.
- * @param defaultValue The default value for the parameter, or {@code null} if none.
- * @return The parameter descriptor for the given default value and unit.
- */
- public <T> ParameterDescriptor<T> create(final Class<T> valueClass, final T defaultValue) {
- return create(valueClass, null, null, defaultValue);
- }
-
- /**
* Creates a descriptor for floating point values greater than zero.
* The zero value is not considered valid. There is no maximal value.
*
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -26,13 +26,14 @@ import java.lang.reflect.ParameterizedTy
import org.opengis.util.NameSpace;
import org.opengis.util.GenericName;
import org.opengis.util.NameFactory;
+import org.opengis.util.InternationalString;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.referencing.IdentifiedObject;
-import org.opengis.referencing.ReferenceIdentifier;
import org.apache.sis.metadata.iso.ImmutableIdentifier;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.Citations;
+import org.apache.sis.util.iso.Types;
import org.apache.sis.util.Deprecable;
import org.apache.sis.util.resources.Errors;
@@ -40,6 +41,7 @@ import static org.apache.sis.util.Argume
// Branch-dependent imports
import org.apache.sis.internal.jdk8.JDK8;
+import org.opengis.referencing.ReferenceIdentifier;
/**
@@ -315,18 +317,6 @@ public abstract class Builder<B extends
}
/**
- * Creates an identifier from a string for the given authority.
- */
- private ReferenceIdentifier createIdentifier(final Citation authority, final String identifier) {
- if (authority == getAuthority()) {
- return new ImmutableIdentifier(authority, getCodeSpace(), identifier, getVersion(), null);
- } else {
- // Do not use the version information since it applies to the default authority rather than the given one.
- return new ImmutableIdentifier(authority, Citations.getCodeSpace(authority), identifier);
- }
- }
-
- /**
* Converts the given name into an identifier. Note that {@link NamedIdentifier}
* implements both {@link GenericName} and {@link Identifier} interfaces.
*/
@@ -455,24 +445,35 @@ public abstract class Builder<B extends
/**
* Adds an {@code IdentifiedObject} name given by a {@code String} or {@code InternationalString}.
- * The given string will be combined with the authority, {@link #setCodeSpace(Citation, String) code space}
- * and {@link #setVersion(String) version} information for creating the {@link Identifier} or {@link GenericName}
- * object.
+ * The given string will be combined with the authority, {@linkplain #setCodeSpace(Citation, String)
+ * code space} and {@linkplain #setVersion(String) version} information for creating the
+ * {@link Identifier} or {@link GenericName} object.
*
* <div class="section">Name and aliases</div>
* This method can be invoked many times. The first invocation sets the
* {@linkplain AbstractIdentifiedObject#getName() primary name}, and
* all subsequent invocations add an {@linkplain AbstractIdentifiedObject#getAlias() alias}.
*
+ * <div class="section">Deprecated names</div>
+ * Some names may exist for historical reasons but have their use discouraged.
+ * If <code>{@linkplain #setDeprecated(boolean) setDeprecated}(true)</code> has been invoked, then this
+ * method creates a deprecated alias with the current {@linkplain #setRemarks(CharSequence) remarks}.
+ * The remark should suggest a replacement, for example with a sentence like
+ * <cite>"Superseded by {@literal <new-name>}"</cite>.
+ *
+ * <p>Note that deprecated names are always added as aliases, never as the primary name of an identified object.</p>
+ *
* <p><b>Lifetime:</b>
* the name and all aliases are cleared after a {@code createXXX(…)} method has been invoked.</p>
*
- * @param name The {@code IdentifiedObject} name.
+ * @param name The {@code IdentifiedObject} name as a {@link String} or {@link InternationalString} instance.
* @return {@code this}, for method call chaining.
*/
public B addName(final CharSequence name) {
ensureNonNull("name", name);
- if (JDK8.putIfAbsent(properties, IdentifiedObject.NAME_KEY, name.toString()) != null) {
+ if (isDeprecated()) {
+ aliases.add(new DeprecatedName(getAuthority(), getCodeSpace(), name, getVersion(), getRemarks()));
+ } else if (JDK8.putIfAbsent(properties, IdentifiedObject.NAME_KEY, name.toString()) != null) {
// A primary name is already present. Add the given name as an alias instead.
aliases.add(createName(name));
}
@@ -509,10 +510,27 @@ public abstract class Builder<B extends
*/
public B addName(final Citation authority, final CharSequence name) {
ensureNonNull("name", name);
- final NamedIdentifier identifier = new NamedIdentifier(authority, name);
- if (JDK8.putIfAbsent(properties, IdentifiedObject.NAME_KEY, identifier) != null) {
+ final boolean isDeprecated = isDeprecated();
+ if (!isDeprecated && properties.get(IdentifiedObject.NAME_KEY) != null) {
// A primary name is already present. Add the given name as an alias instead.
- aliases.add(identifier);
+ aliases.add(createName(authority, name));
+ } else {
+ final String codeSpace;
+ final String version;
+ if (authority == getAuthority()) {
+ codeSpace = getCodeSpace();
+ version = getVersion();
+ } else {
+ // Do not use the version information since it applies to the default authority rather than the given one.
+ codeSpace = Citations.getCodeSpace(authority);
+ version = null;
+ }
+ if (isDeprecated) {
+ aliases.add(new DeprecatedName(authority, codeSpace, name, version, getRemarks()));
+ } else {
+ properties.put(IdentifiedObject.NAME_KEY,
+ new NamedIdentifier(authority, codeSpace, name, version, getDescription()));
+ }
}
return self();
}
@@ -571,38 +589,17 @@ public abstract class Builder<B extends
}
/**
- * Adds a deprecated name given by a {@code CharSequence}. Some objects have deprecated names for historical reasons.
- * The deprecated name typically has a replacement, which can be given by the {@code supersededBy} argument.
- * The later, if non-null, shall be a name specified by a previous call to an {@code addName(…)} method.
- *
- * <p>The given string will be combined with the authority, {@link #setCodeSpace(Citation, String) code space} and
- * {@link #setVersion(String) version} information for creating the deprecated {@link NamedIdentifier} object.</p>
- *
- * <p><b>Lifetime:</b>
- * all identifiers are cleared after a {@code createXXX(…)} method has been invoked.</p>
- *
- * @param name The {@code IdentifiedObject} deprecated name.
- * @param supersededBy The name to use instead of this one, or {@code null} if none.
- * @return {@code this}, for method call chaining.
- *
- * @see #addDeprecatedIdentifier(String, String)
- * @see #setDeprecated(boolean)
- *
- * @since 0.6
- */
- public B addDeprecatedName(final CharSequence name, final CharSequence supersededBy) {
- ensureNonNull("name", name);
- final DeprecatedName dn = new DeprecatedName(getAuthority(), getCodeSpace(), name, getVersion(), supersededBy);
- if (JDK8.putIfAbsent(properties, IdentifiedObject.NAME_KEY, dn) != null) {
- aliases.add(dn);
- }
- return self();
- }
-
- /**
* Adds an {@code IdentifiedObject} identifier given by a {@code String}.
- * The given string will be combined with the authority, {@link #setCodeSpace(Citation, String) code space}
- * and {@link #setVersion(String) version} information for creating the {@link Identifier} object.
+ * The given string will be combined with the authority, {@linkplain #setCodeSpace(Citation, String) code space}
+ * {@linkplain #setVersion(String) version} and {@linkplain #setDescription(CharSequence) description} information
+ * for creating the {@link Identifier} object.
+ *
+ * <div class="section">Deprecated identifiers</div>
+ * Some identifiers may exist for historical reasons but have their use discouraged.
+ * If <code>{@linkplain #setDeprecated(boolean) setDeprecated}(true)</code> has been invoked, then this
+ * method creates a deprecated identifier with the current {@linkplain #setRemarks(CharSequence) remarks}.
+ * The remark should suggest a replacement, for example with a sentence like
+ * <cite>"Superseded by {@literal <new-code>}"</cite>.
*
* <p><b>Lifetime:</b>
* all identifiers are cleared after a {@code createXXX(…)} method has been invoked.</p>
@@ -612,7 +609,7 @@ public abstract class Builder<B extends
*/
public B addIdentifier(final String identifier) {
ensureNonNull("identifier", identifier);
- identifiers.add(new ImmutableIdentifier(getAuthority(), getCodeSpace(), identifier, getVersion(), null));
+ addIdentifier(getAuthority(), getCodeSpace(), identifier, getVersion());
return self();
}
@@ -623,7 +620,7 @@ public abstract class Builder<B extends
* <p><b>Lifetime:</b>
* all identifiers are cleared after a {@code createXXX(…)} method has been invoked.</p>
*
- * @param authority Bibliographic reference to the authority defining the codes, or {@code null} if none.
+ * @param authority Bibliographic reference to the authority defining the codes, or {@code null} if none.
* @param identifier The {@code IdentifiedObject} identifier as a code in the namespace of the given authority.
* @return {@code this}, for method call chaining.
*
@@ -631,15 +628,38 @@ public abstract class Builder<B extends
*/
public B addIdentifier(final Citation authority, final String identifier) {
ensureNonNull("identifier", identifier);
- identifiers.add(createIdentifier(authority, identifier));
+ final String codeSpace;
+ final String version;
+ if (authority == getAuthority()) {
+ codeSpace = getCodeSpace();
+ version = getVersion();
+ } else {
+ // Do not use the version information since it applies to the default authority rather than the given one.
+ codeSpace = Citations.getCodeSpace(authority);
+ version = null;
+ }
+ addIdentifier(authority, codeSpace, identifier, version);
return self();
}
/**
+ * Implementation of {@link #addIdentifier(String)} and {@link #addIdentifier(Citation, String)}.
+ */
+ private void addIdentifier(final Citation authority, final String codeSpace, final String identifier, final String version) {
+ final ReferenceIdentifier id;
+ if (isDeprecated()) {
+ id = new DeprecatedCode(authority, codeSpace, identifier, version, getRemarks());
+ } else {
+ id = new ImmutableIdentifier(authority, codeSpace, identifier, version, getDescription());
+ }
+ identifiers.add(id);
+ }
+
+ /**
* Adds an {@code IdentifiedObject} identifier fully specified by the given identifier.
- * This method ignores the authority, {@link #setCodeSpace(Citation, String) code space} or
- * {@link #setVersion(String) version} specified to this builder (if any), since the given
- * identifier already contains those information.
+ * This method ignores the authority, {@linkplain #setCodeSpace(Citation, String) code space},
+ * {@linkplain #setVersion(String) version} and {@linkplain #setDescription(CharSequence) description}
+ * specified to this builder (if any), since the given identifier already contains those information.
*
* <p><b>Lifetime:</b>
* all identifiers are cleared after a {@code createXXX(…)} method has been invoked.</p>
@@ -653,35 +673,11 @@ public abstract class Builder<B extends
return self();
}
- /**
- * Adds a deprecated identifier given by a {@code String}. Some objects have deprecated identifiers for
- * historical reasons. The deprecated identifier typically has a replacement, which can be given by the
- * {@code supersededBy} argument. The later, if non-null, shall be an identifier specified by a previous
- * call to an {@code addIdentifier(…)} method.
- *
- * <p>The given string will be combined with the authority, {@link #setCodeSpace(Citation, String) code space}
- * and {@link #setVersion(String) version} information for creating the deprecated {@link Identifier} object.</p>
- *
- * <p><b>Lifetime:</b>
- * all identifiers are cleared after a {@code createXXX(…)} method has been invoked.</p>
- *
- * @param identifier The {@code IdentifiedObject} deprecated identifier.
- * @param supersededBy The identifier to use instead of this one, or {@code null} if none.
- * @return {@code this}, for method call chaining.
- *
- * @see #addDeprecatedName(CharSequence, CharSequence)
- * @see #setDeprecated(boolean)
- *
- * @since 0.6
- */
- public B addDeprecatedIdentifier(final String identifier, final String supersededBy) {
- ensureNonNull("identifier", identifier);
- identifiers.add(new DeprecatedCode(getAuthority(), getCodeSpace(), identifier, getVersion(), supersededBy));
- return self();
- }
/**
* Returns {@code true} if the given name or identifier is deprecated.
+ *
+ * @see #isDeprecated()
*/
private static boolean isDeprecated(final Object object) {
return (object instanceof Deprecable) && ((Deprecable) object).isDeprecated();
@@ -805,22 +801,57 @@ public abstract class Builder<B extends
}
/**
- * Sets the parameter description as a {@code String} or {@code InternationalString} instance.
+ * Returns the parameter description specified by the last call to {@link #setDescription(CharSequence)},
+ * or {@code null} if none.
+ */
+ private InternationalString getDescription() {
+ return (InternationalString) properties.get("description");
+ }
+
+ /**
+ * Sets an {@code Identifier} or {@code IdentifiedObject} description.
+ * Descriptions can be used in various contexts:
+ *
+ * <ul>
+ * <li>Before calls to {@link #addIdentifier(String)} or {@link #addIdentifier(Citation, String)}
+ * for specifying a natural language description of the meaning of the code value.
+ *
+ * <div class="note"><b>Example:</b>
+ * {@code setDescription("World Geodetic System 1984").addIdentifier("4326")}</div></li>
+ *
+ * <li>Before calls to a {@code createXXX(…)} method for providing a narrative explanation
+ * of the role of the object. Not all {@code IdentifiedObject} supports description.</li>
+ * </ul>
+ *
* Calls to this method overwrite any previous value.
*
* <p><b>Lifetime:</b>
* previous descriptions are discarded by calls to {@code setDescription(…)}.
* Descriptions are cleared after a {@code createXXX(…)} method has been invoked.</p>
*
- * @param description The description, or {@code null} if none.
+ * @param description The description as a {@link String} or {@link InternationalString} instance, or {@code null} if none.
* @return {@code this}, for method call chaining.
+ *
+ * @see ImmutableIdentifier#getDescription()
*/
public B setDescription(final CharSequence description) {
- properties.put("description", description);
+ /*
+ * Convert to InternationalString now in order to share the same instance if
+ * the same description is used both for an Identifier and an IdentifiedObject.
+ */
+ properties.put("description", Types.toInternationalString(description));
return self();
}
/**
+ * Returns the remarks specified by the last call to {@link #setRemarks(CharSequence)},
+ * or {@code null} if none.
+ */
+ private InternationalString getRemarks() {
+ return (InternationalString) properties.get(IdentifiedObject.REMARKS_KEY);
+ }
+
+ /**
* Sets remarks as a {@code String} or {@code InternationalString} instance.
* Calls to this method overwrite any previous value.
*
@@ -828,30 +859,40 @@ public abstract class Builder<B extends
* previous remarks are discarded by calls to {@code setRemarks(…)}.
* Remarks are cleared after a {@code createXXX(…)} method has been invoked.</p>
*
- * @param remarks The remarks, or {@code null} if none.
+ * @param remarks The remarks as a {@link String} or {@link InternationalString} instance, or {@code null} if none.
* @return {@code this}, for method call chaining.
*/
public B setRemarks(final CharSequence remarks) {
- properties.put(IdentifiedObject.REMARKS_KEY, remarks);
+ /*
+ * Convert to InternationalString now in order to share the same instance if
+ * the same remarks is used both for an Identifier and an IdentifiedObject.
+ */
+ properties.put(IdentifiedObject.REMARKS_KEY, Types.toInternationalString(remarks));
return self();
}
/**
- * Sets whether the next {@code IdentifiedObject}s to create shall be considered deprecated. Deprecated objects
- * exist in some {@linkplain org.opengis.referencing.AuthorityFactory authority factories} like the EPSG database.
+ * Returns {@code true} if the deprecated flag is set to {@code true}.
+ */
+ private boolean isDeprecated() {
+ return Boolean.TRUE.equals(properties.get(AbstractIdentifiedObject.DEPRECATED_KEY));
+ }
+
+ /**
+ * Sets whether the next {@code Identifier} or {@code IdentifiedObject}s to create shall be considered deprecated.
+ * Deprecated objects exist in some {@linkplain org.opengis.referencing.AuthorityFactory authority factories} like
+ * the EPSG database.
*
* <p>Note that this method does not apply to name and identifiers, which have their own
* {@code addDeprecatedFoo(…)} methods.</p>
*
* <p><b>Lifetime:</b>
- * this property is kept unchanged until this {@code setDeprecated(…)} method is invoked again.</p>
+ * Deprecation status is cleared after a {@code createXXX(…)} method has been invoked.</p>
*
* @param deprecated {@code true} if the next names, identifiers and identified objects should be
* considered deprecated, or {@code false} otherwise.
* @return {@code this}, for method call chaining.
*
- * @see #addDeprecatedName(CharSequence, CharSequence)
- * @see #addDeprecatedIdentifier(String, String)
* @see AbstractIdentifiedObject#isDeprecated()
*
* @since 0.6
@@ -879,8 +920,9 @@ public abstract class Builder<B extends
* }
*
* If {@code cleanup} is {@code true}, then this method clears the identification information
- * (name, aliases, identifiers and remarks) for preparing the builder to the construction of
- * an other object. The authority, codespace and version properties are not cleared by this method.
+ * (name, aliases, identifiers, description, remarks and deprecation status) for preparing the
+ * builder to the construction of an other object.
+ * The authority, codespace and version properties are not cleared by this method.
*
* @param cleanup {@code false} when this method is invoked before object creation, and
* {@code true} when this method is invoked after object creation.
@@ -893,12 +935,14 @@ public abstract class Builder<B extends
if (cleanup) {
properties .put(IdentifiedObject.NAME_KEY, null);
properties .remove(IdentifiedObject.REMARKS_KEY);
+ properties .remove("description");
+ properties .remove(AbstractIdentifiedObject.DEPRECATED_KEY);
aliases .clear();
identifiers.clear();
valueAlias = null;
valueIds = null;
} else {
- valueAlias = aliases .toArray(new GenericName[aliases.size()]);
+ valueAlias = aliases .toArray(new GenericName[aliases .size()]);
valueIds = identifiers.toArray(new ReferenceIdentifier[identifiers.size()]);
}
properties.put(IdentifiedObject.ALIAS_KEY, valueAlias);
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -20,7 +20,6 @@ import org.opengis.util.InternationalStr
import org.opengis.metadata.citation.Citation;
import org.apache.sis.metadata.iso.ImmutableIdentifier;
import org.apache.sis.util.Deprecable;
-import org.apache.sis.util.resources.Vocabulary;
/**
@@ -46,14 +45,11 @@ final class DeprecatedCode extends Immut
/**
* Creates a deprecated identifier.
- *
- * @param supersededBy The code that replace this one.
*/
DeprecatedCode(final Citation authority, final String codeSpace,
- final String code, final String version, final CharSequence supersededBy)
+ final String code, final String version, final InternationalString remarks)
{
- super(authority, codeSpace, code, version,
- Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, supersededBy));
+ super(authority, codeSpace, code, version, remarks);
}
/**
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedName.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedName.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedName.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedName.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -18,7 +18,6 @@ package org.apache.sis.referencing;
import org.opengis.util.InternationalString;
import org.opengis.metadata.citation.Citation;
-import org.apache.sis.util.resources.Vocabulary;
/**
@@ -49,10 +48,10 @@ final class DeprecatedName extends Named
* @param supersededBy The name that replace this one.
*/
DeprecatedName(final Citation authority, final String codeSpace, final CharSequence code, final String version,
- final CharSequence supersededBy)
+ final InternationalString remarks)
{
super(authority, codeSpace, code, version, null);
- remarks = Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, supersededBy);
+ this.remarks = remarks;
}
/**
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -17,9 +17,13 @@
package org.apache.sis.referencing.operation.projection;
import java.util.EnumMap;
+import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.OperationMethod;
+import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.internal.referencing.provider.TransverseMercatorSouth;
import org.apache.sis.internal.util.DoubleDouble;
@@ -51,6 +55,7 @@ import static org.apache.sis.math.MathFu
* all zones and a false northing of 10000000 metres is used for zones in the southern hemisphere.
*
* @author Martin Desruisseaux (Geomatys)
+ * @author Rémi Maréchal (Geomatys)
* @since 0.6
* @version 0.6
* @module
@@ -200,6 +205,42 @@ public class TransverseMercator extends
}
/**
+ * Creates a new projection initialized to the same parameters than the given one.
+ */
+ TransverseMercator(final TransverseMercator other) {
+ super(other);
+ h1 = other. h1;
+ h2 = other. h2;
+ h3 = other. h3;
+ h4 = other. h4;
+ ih1 = other.ih1;
+ ih2 = other.ih2;
+ ih3 = other.ih3;
+ ih4 = other.ih4;
+ }
+
+ /**
+ * Returns the sequence of <cite>normalization</cite> → {@code this} → <cite>denormalization</cite> transforms
+ * as a whole. The transform returned by this method except (<var>longitude</var>, <var>latitude</var>)
+ * coordinates in <em>degrees</em> and returns (<var>x</var>,<var>y</var>) coordinates in <em>metres</em>.
+ *
+ * <p>The non-linear part of the returned transform will be {@code this} transform, except if the ellipsoid
+ * is spherical. In the later case, {@code this} transform will be replaced by a simplified implementation.</p>
+ *
+ * @param factory The factory to use for creating the transform.
+ * @return The map projection from (λ,φ) to (<var>x</var>,<var>y</var>) coordinates.
+ * @throws FactoryException if an error occurred while creating a transform.
+ */
+ @Override
+ public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
+ TransverseMercator kernel = this;
+ if (excentricity == 0) {
+ kernel = new Spherical(this);
+ }
+ return context.completeTransform(factory, kernel);
+ }
+
+ /**
* Converts the specified (λ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
* In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
*
@@ -212,44 +253,139 @@ public class TransverseMercator extends
final double[] dstPts, final int dstOff,
final boolean derivate) throws ProjectionException
{
- final double λ = srcPts[srcOff];
- final double φ = srcPts[srcOff + 1];
- final double Q = asinh(tan(φ)) - atanh(sin(φ)*excentricity)*excentricity;
- final double β = atan(sinh(Q));
-
- // TODO: sin(atan(x)) = x / sqrt(1+x²)
- // cos(atan(x)) = 1 / sqrt(1+x²)
- final double η0 = atanh(cos(β) * sin(λ));
- final double ξ0 = asin(sin(β) * cosh(η0));
+ final double λ = srcPts[srcOff];
+ final double φ = srcPts[srcOff + 1];
- // TODO: use trigonometric identities.
- // See ConformalProjection for example.
- final double ξ = h4 * sin(8*ξ0) * cosh(8*η0)
- + h3 * sin(6*ξ0) * cosh(6*η0)
- + h2 * sin(4*ξ0) * cosh(4*η0)
- + h1 * sin(2*ξ0) * cosh(2*η0)
+ final double ℯsinφ = excentricity * sin(φ);
+ final double Q = asinh(tan(φ)) - atanh(ℯsinφ) * excentricity;
+ final double sinλ = sin(λ);
+ final double coshQ = cosh(Q);
+ final double η0 = atanh(sinλ / coshQ);
+
+ /*
+ * Original formula: η0 = atanh(sin(λ) * cos(β)) where
+ * cos(β) = cos(atan(sinh(Q)))
+ * = 1 / sqrt(1 + sinh²(Q))
+ * = 1 / (sqrt(cosh²(Q) - sinh²(Q) + sinh²(Q)))
+ * = 1 / sqrt(cosh²(Q))
+ * = 1 / cosh(Q)
+ *
+ * So η0 = atanh(sin(λ) / cosh(Q))
+ */
+ final double coshη0 = cosh(η0);
+ final double ξ0 = asin(tanh(Q) * coshη0);
+
+ //-- ξ0
+ final double sin_8ξ0 = sin(8*ξ0);
+ final double sin_6ξ0 = sin(6*ξ0);
+ final double sin_4ξ0 = sin(4*ξ0);
+ final double sin_2ξ0 = sin(2*ξ0);
+ final double cos_8ξ0 = cos(8*ξ0);
+ final double cos_6ξ0 = cos(6*ξ0);
+ final double cos_4ξ0 = cos(4*ξ0);
+ final double cos_2ξ0 = cos(2*ξ0);
+
+ //-- η0
+ final double cosh_8η0 = cosh(8*η0);
+ final double cosh_6η0 = cosh(6*η0);
+ final double cosh_4η0 = cosh(4*η0);
+ final double cosh_2η0 = cosh(2*η0);
+ final double sinh_8η0 = sinh(8*η0);
+ final double sinh_6η0 = sinh(6*η0);
+ final double sinh_4η0 = sinh(4*η0);
+ final double sinh_2η0 = sinh(2*η0);
+
+ /*
+ * Assuming that (λ, φ) ↦ Proj((λ, φ))
+ * where Proj is defined by: Proj((λ, φ)) : (η(λ, φ), ξ(λ, φ)).
+ *
+ * => (λ, φ) ↦ (η(λ, φ), ξ(λ, φ)).
+ */
+ //-- ξ(λ, φ)
+ final double ξ = h4 * sin_8ξ0 * cosh_8η0
+ + h3 * sin_6ξ0 * cosh_6η0
+ + h2 * sin_4ξ0 * cosh_4η0
+ + h1 * sin_2ξ0 * cosh_2η0
+ ξ0;
- final double η = h4 * cos(8*ξ0) * sinh(8*η0)
- + h3 * cos(6*ξ0) * sinh(6*η0)
- + h2 * cos(4*ξ0) * sinh(4*η0)
- + h1 * cos(2*ξ0) * sinh(2*η0)
+ //-- η(λ, φ)
+ final double η = h4 * cos_8ξ0 * sinh_8η0
+ + h3 * cos_6ξ0 * sinh_6η0
+ + h2 * cos_4ξ0 * sinh_4η0
+ + h1 * cos_2ξ0 * sinh_2η0
+ η0;
if (dstPts != null) {
dstPts[dstOff ] = η;
dstPts[dstOff + 1] = ξ;
}
+
if (!derivate) {
return null;
}
- // TODO: compute projection derivative.
- return null;
+ final double cosλ = cos(λ); //-- λ
+ final double cosφ = cos(φ); //-- φ
+ final double cosh2Q = coshQ * coshQ; //-- Q
+ final double sinhQ = sinh(Q);
+ final double tanhQ = tanh(Q);
+ final double cosh2Q_sin2λ = cosh2Q - sinλ * sinλ; //-- Qλ
+ final double sinhη0 = sinh(η0); //-- η0
+ final double sqrt1_thQchη0 = sqrt(1 - tanhQ * tanhQ * coshη0 * coshη0); //-- Qη0
+
+ //-- dQ_dλ = 0;
+ final double dQ_dφ = 1 / cosφ - excentricitySquared * cosφ / (1 - ℯsinφ * ℯsinφ);
+
+ final double dη0_dλ = cosλ * coshQ / cosh2Q_sin2λ;
+ final double dη0_dφ = - dQ_dφ * sinλ * sinhQ / cosh2Q_sin2λ;
+
+ final double dξ0_dλ = sinhQ * sinhη0 * cosλ / (cosh2Q_sin2λ * sqrt1_thQchη0);
+ final double dξ0_dφ = (dQ_dφ * coshη0 / cosh2Q + dη0_dφ * sinhη0 * tanhQ) / sqrt1_thQchη0;
+
+ /*
+ * Assuming that Jac(Proj((λ, φ))) is the Jacobian matrix of Proj((λ, φ)) function.
+ *
+ * So derivative Proj((λ, φ)) is defined by:
+ * ┌ ┐
+ * │ dη(λ, φ) / dλ, dη(λ, φ) / dφ │
+ * Jac = │ │
+ * (Proj(λ, φ)) │ dξ(λ, φ) / dλ, dξ(λ, φ) / dφ │
+ * └ ┘
+ */
+ //-- dξ(λ, φ) / dλ
+ final double dξ_dλ = dξ0_dλ
+ + 2 * (h1 * (dξ0_dλ * cos_2ξ0 * cosh_2η0 + dη0_dλ * sinh_2η0 * sin_2ξ0)
+ + 3 * h3 * (dξ0_dλ * cos_6ξ0 * cosh_6η0 + dη0_dλ * sinh_6η0 * sin_6ξ0)
+ + 2 * (h2 * (dξ0_dλ * cos_4ξ0 * cosh_4η0 + dη0_dλ * sinh_4η0 * sin_4ξ0)
+ + 2 * h4 * (dξ0_dλ * cos_8ξ0 * cosh_8η0 + dη0_dλ * sinh_8η0 * sin_8ξ0)));
+
+ //-- dξ(λ, φ) / dφ
+ final double dξ_dφ = dξ0_dφ
+ + 2 * (h1 * (dξ0_dφ * cos_2ξ0 * cosh_2η0 + dη0_dφ * sinh_2η0 * sin_2ξ0)
+ + 3 * h3 * (dξ0_dφ * cos_6ξ0 * cosh_6η0 + dη0_dφ * sinh_6η0 * sin_6ξ0)
+ + 2 * (h2 * (dξ0_dφ * cos_4ξ0 * cosh_4η0 + dη0_dφ * sinh_4η0 * sin_4ξ0)
+ + 2 * h4 * (dξ0_dφ * cos_8ξ0 * cosh_8η0 + dη0_dφ * sinh_8η0 * sin_8ξ0)));
+
+ //-- dη(λ, φ) / dλ
+ final double dη_dλ = dη0_dλ
+ + 2 * (h1 * (dη0_dλ * cosh_2η0 * cos_2ξ0 - dξ0_dλ * sin_2ξ0 * sinh_2η0)
+ + 3 * h3 * (dη0_dλ * cosh_6η0 * cos_6ξ0 - dξ0_dλ * sin_6ξ0 * sinh_6η0)
+ + 2 * (h2 * (dη0_dλ * cosh_4η0 * cos_4ξ0 - dξ0_dλ * sin_4ξ0 * sinh_4η0)
+ + 2 * h4 * (dη0_dλ * cosh_8η0 * cos_8ξ0 - dξ0_dλ * sin_8ξ0 * sinh_8η0)));
+
+ //-- dη(λ, φ) / dφ
+ final double dη_dφ = dη0_dφ
+ + 2 * (h1 * (dη0_dφ * cosh_2η0 * cos_2ξ0 - dξ0_dφ * sin_2ξ0 * sinh_2η0)
+ + 3 * h3 * (dη0_dφ * cosh_6η0 * cos_6ξ0 - dξ0_dφ * sin_6ξ0 * sinh_6η0)
+ + 2 * (h2 * (dη0_dφ * cosh_4η0 * cos_4ξ0 - dξ0_dφ * sin_4ξ0 * sinh_4η0)
+ + 2 * h4 * (dη0_dφ * cosh_8η0 * cos_8ξ0 - dξ0_dφ * sin_8ξ0 * sinh_8η0)));
+
+ return new Matrix2(dη_dλ, dη_dφ,
+ dξ_dλ, dξ_dφ);
}
/**
- * Transforms the specified (η,ξ) coordinates and stores the result in {@code dstPts} (angles in radians).
+ * Transforms the specified (η, ξ) coordinates and stores the result in {@code dstPts} (angles in radians).
*
* @throws ProjectionException if the point can not be converted.
*/
@@ -291,4 +427,83 @@ public class TransverseMercator extends
}
throw new ProjectionException(Errors.Keys.NoConvergence);
}
+
+
+ /**
+ * Provides the transform equations for the spherical case of the Transverse Mercator projection.
+ *
+ * @author André Gosselin (MPO)
+ * @author Martin Desruisseaux (IRD, Geomatys)
+ * @author Rueben Schulz (UBC)
+ * @since 0.6
+ * @version 0.6
+ * @module
+ */
+ private static final class Spherical extends TransverseMercator {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 8903592710452235162L;
+
+ /**
+ * Constructs a new map projection from the parameters of the given projection.
+ *
+ * @param other The other projection (usually ellipsoidal) from which to copy the parameters.
+ */
+ protected Spherical(final TransverseMercator other) {
+ super(other);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Matrix transform(final double[] srcPts, final int srcOff,
+ final double[] dstPts, final int dstOff,
+ final boolean derivate) throws ProjectionException
+ {
+ final double λ = srcPts[srcOff];
+ final double φ = srcPts[srcOff + 1];
+ final double sinλ = sin(λ);
+ final double cosλ = cos(λ);
+ final double sinφ = sin(φ);
+ final double cosφ = cos(φ);
+ final double tanφ = sinφ / cosφ;
+ final double B = cosφ * sinλ;
+ /*
+ * Using Snyder's equation for calculating y, instead of the one used in Proj4.
+ * Potential problems when y and x = 90 degrees, but behaves ok in tests.
+ */
+ if (dstPts != null) {
+ dstPts[dstOff ] = atanh(B); // Snyder 8-1;
+ dstPts[dstOff+1] = atan2(tanφ, cosλ); // Snyder 8-3;
+ }
+ if (!derivate) {
+ return null;
+ }
+ final double Bm = B*B - 1;
+ final double sct = cosλ*cosλ + tanφ*tanφ;
+ return new Matrix2(-(cosφ * cosλ) / Bm, // ∂x/∂λ
+ (sinφ * sinλ) / Bm, // ∂x/∂φ
+ (tanφ * sinλ) / sct, // ∂y/∂λ
+ cosλ / (cosφ * cosφ * sct)); // ∂y/∂φ
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void inverseTransform(final double[] srcPts, final int srcOff,
+ final double[] dstPts, final int dstOff)
+ throws ProjectionException
+ {
+ final double x = srcPts[srcOff ];
+ final double y = srcPts[srcOff+1];
+ final double sinhx = sinh(x);
+ final double cosy = cos(y);
+ // 'copySign' corrects for the fact that we made everything positive using sqrt(…)
+ dstPts[dstOff ] = atan2(sinhx, cosy);
+ dstPts[dstOff+1] = copySign(asin(sqrt((1 - cosy*cosy) / (1 + sinhx*sinhx))), y);
+ }
+ }
}
Modified: sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Wed Sep 9 14:43:51 2015
@@ -14,6 +14,8 @@ org.apache.sis.internal.referencing.prov
org.apache.sis.internal.referencing.provider.LambertConformalWest
org.apache.sis.internal.referencing.provider.LambertConformalBelgium
org.apache.sis.internal.referencing.provider.LambertConformalMichigan
+org.apache.sis.internal.referencing.provider.TransverseMercator
+org.apache.sis.internal.referencing.provider.TransverseMercatorSouth
org.apache.sis.internal.referencing.provider.PolarStereographicA
org.apache.sis.internal.referencing.provider.PolarStereographicB
org.apache.sis.internal.referencing.provider.PolarStereographicC
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -349,7 +349,7 @@ public final class CoordinateOperationMe
remarks = "Optional ";
} else {
final Comparable<?> min = param.getMinimumValue();
- if (min != null && min.equals(param.getMaximumValue())) {
+ if ((min instanceof Number) && ((Number) min).doubleValue() == ((Number) param.getMaximumValue()).doubleValue()) {
remarks = "Unmodifiable ";
} else {
remarks = "See note ";
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConicConformalTest.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -71,7 +71,7 @@ public final strictfp class LambertConic
a = a.multiply(new BigDecimal("57.29577951308232087679815481410517")); // Conversion from radians to degrees.
a = a.multiply(new BigDecimal(60 * 60)); // Conversion from degrees to seconds.
a = a.add (new BigDecimal("29.2985")); // The standard value.
- assertTrue(Math.abs(a.doubleValue()) < 1E-31);
+ assertTrue(abs(a.doubleValue()) < 1E-31);
}
/**
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java?rev=1702031&r1=1702030&r2=1702031&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java [UTF-8] Wed Sep 9 14:43:51 2015
@@ -18,8 +18,11 @@ package org.apache.sis.referencing.opera
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.referencing.provider.TransverseMercatorSouth;
import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.operation.transform.CoordinateDomain;
+import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.junit.Test;
@@ -61,7 +64,6 @@ public final strictfp class TransverseMe
* @see org.opengis.test.referencing.ParameterizedTransformTest#testTransverseMercator()
*/
@Test
- @org.junit.Ignore("Missing implementation of the projection derivative.")
public void testTransverseMercator() throws FactoryException, TransformException {
new org.apache.sis.internal.referencing.provider.TransverseMercator(); // Test creation only, as GeoAPI 3.0 did not yet had the test method.
}
@@ -76,18 +78,39 @@ public final strictfp class TransverseMe
* @see org.opengis.test.referencing.ParameterizedTransformTest#testTransverseMercatorSouthOrientated()
*/
@Test
- @org.junit.Ignore("Missing implementation of the projection derivative.")
+ @DependsOnMethod("testTransverseMercator")
public void testTransverseMercatorSouthOrientated() throws FactoryException, TransformException {
new TransverseMercatorSouth(); // Test creation only, as GeoAPI 3.0 did not yet had the test method.
}
/**
+ * Verifies the consistency of elliptical formulas with the spherical formulas.
+ * This test compares the results of elliptical formulas with the spherical ones
+ * for some random points.
+ *
+ * @throws FactoryException if an error occurred while creating the map projection.
+ * @throws TransformException if an error occurred while projecting a coordinate.
+ */
+ @Test
+ @DependsOnMethod("testTransverseMercator")
+ public void compareEllipticalWithSpherical() throws FactoryException, TransformException {
+ createCompleteProjection(new org.apache.sis.internal.referencing.provider.TransverseMercator(), false,
+ 0.5, // Central meridian
+ 2.5, // Latitude of origin
+ 0, // Standard parallel (none)
+ 0.997, // Scale factor
+ 200, // False easting
+ 100); // False northing
+ tolerance = Formulas.LINEAR_TOLERANCE;
+ compareEllipticalWithSpherical(CoordinateDomain.RANGE_10, 0);
+ }
+
+ /**
* Creates a projection and derivates a few points.
*
* @throws TransformException Should never happen.
*/
@Test
- @org.junit.Ignore("Missing implementation of the projection derivative.")
public void testSphericalDerivative() throws TransformException {
createNormalizedProjection(false, 0);
tolerance = 1E-9;
@@ -105,7 +128,6 @@ public final strictfp class TransverseMe
* @throws TransformException Should never happen.
*/
@Test
- @org.junit.Ignore("Missing implementation of the projection derivative.")
public void testEllipsoidalDerivative() throws TransformException {
createNormalizedProjection(true, 0);
tolerance = 1E-9;