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 2016/01/14 00:25:42 UTC
svn commit: r1724528 [8/15] - in /sis/branches/JDK6: ./
application/sis-console/src/main/artifact/bin/
application/sis-console/src/main/artifact/log/
application/sis-console/src/main/java/org/apache/sis/console/
core/sis-build-helper/src/main/java/org/...
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -17,28 +17,17 @@
package org.apache.sis.referencing.operation.transform;
import java.util.Arrays;
-import java.io.Serializable;
import javax.measure.unit.Unit;
-import javax.measure.quantity.Length;
-import javax.measure.converter.UnitConverter;
import org.opengis.util.FactoryException;
-import org.opengis.geometry.DirectPosition;
-import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.operation.matrix.Matrices;
-import org.apache.sis.referencing.datum.DefaultEllipsoid;
import org.apache.sis.internal.referencing.provider.Molodensky;
import org.apache.sis.internal.referencing.provider.AbridgedMolodensky;
-import org.apache.sis.internal.referencing.provider.MapProjection;
-import org.apache.sis.internal.util.Numerics;
import org.apache.sis.parameter.Parameters;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Debug;
import static java.lang.Math.*;
@@ -79,6 +68,16 @@ import static java.lang.Math.*;
* axes (usually metres).</li>
* </ul>
*
+ * <div class="section">Comparison of Molodensky and geocentric translation</div>
+ * Compared to the <cite>"Geocentric translation (geographic domain)"</cite> method,
+ * the Molodensky method has errors usually within a few centimetres.
+ * The Abridged Molodensky method has more noticeable errors, of a few tenths of centimetres.
+ *
+ * <p>Another difference between Molodensky and geocentric translation methods is their behavior when crossing the
+ * anti-meridian. If a datum shift causes a longitude to cross the anti-meridian (e.g. 179.999° become 180.001°),
+ * the Molodensky method will keep 180.001° as-is while the geocentric translation method will wrap the longitude
+ * to -179.999°. Such wrap-around behavior may or may not be desired, depending on the applications.</p>
+ *
* @author Rueben Schulz (UBC)
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Rémi Maréchal (Geomatys)
@@ -86,7 +85,7 @@ import static java.lang.Math.*;
* @version 0.7
* @module
*/
-public class MolodenskyTransform extends AbstractMathTransform implements Serializable {
+public class MolodenskyTransform extends MolodenskyFormula {
/**
* Serial number for inter-operability with different versions.
*/
@@ -102,107 +101,19 @@ public class MolodenskyTransform extends
private static ParameterDescriptorGroup DESCRIPTOR;
/**
- * The value of 1/sin(1″) multiplied by the conversion factor from arc-seconds to radians (π/180)/(60⋅60).
- * This is the final multiplication factor for Δλ and Δφ.
- */
- private static final double ANGULAR_SCALE = 1.00000000000391744;
-
- /**
- * {@code true} if the source coordinates have a height.
- */
- private final boolean isSource3D;
-
- /**
- * {@code true} if the target coordinates have a height.
- */
- private final boolean isTarget3D;
-
- /**
- * {@code true} for the abridged formula, or {@code false} for the complete one.
- */
- private final boolean isAbridged;
-
- /**
- * Shift along the geocentric X axis (toward prime meridian)
- * in units of the semi-major axis of the source ellipsoid.
- *
- * @see org.apache.sis.referencing.datum.BursaWolfParameters#tX
- */
- protected final double tX;
-
- /**
- * Shift along the geocentric Y axis (toward 90°E)
- * in units of the semi-major axis of the source ellipsoid.
- *
- * @see org.apache.sis.referencing.datum.BursaWolfParameters#tY
- */
- protected final double tY;
-
- /**
- * Shift along the geocentric Z axis (toward north pole)
- * in units of the semi-major axis of the source ellipsoid.
- *
- * @see org.apache.sis.referencing.datum.BursaWolfParameters#tZ
- */
- protected final double tZ;
-
- /**
- * Semi-major axis length (<var>a</var>) of the source ellipsoid.
- */
- private final double semiMajor;
-
- /**
- * The square of eccentricity of the source ellipsoid.
- * This can be computed by ℯ² = (a²-b²)/a² where
- * <var>a</var> is the <cite>semi-major</cite> axis length and
- * <var>b</var> is the <cite>semi-minor</cite> axis length.
- *
- * @see DefaultEllipsoid#getEccentricitySquared()
- */
- private final double eccentricitySquared;
-
- /**
- * Difference in the semi-major axes of the target and source ellipsoids: {@code Δa = target a - source a}.
- *
- * @see DefaultEllipsoid#semiMajorAxisDifference(Ellipsoid)
- */
- private final double Δa;
-
- /**
- * Difference between the flattening of the target and source ellipsoids (Δf), opportunistically modified
- * with additional terms. The value depends on whether this Molodensky transform is abridged or not:
- *
- * <ul>
- * <li>For Molodensky, this field is set to (b⋅Δf).</li>
- * <li>For Abridged Molodensky, this field is set to (a⋅Δf) + (f⋅Δa).</li>
- * </ul>
- *
- * where Δf = <var>target flattening</var> - <var>source flattening</var>.
- */
- private final double Δfmod;
-
- /**
- * The parameters used for creating this conversion.
- * They are used for formatting <cite>Well Known Text</cite> (WKT) and error messages.
- *
- * @see #getContextualParameters()
- */
- private final ContextualParameters context;
-
- /**
* The inverse of this Molodensky transform.
*
* @see #inverse()
*/
- private MolodenskyTransform inverse;
+ private final MolodenskyTransform inverse;
/**
* Creates a Molodensky transform from the specified parameters.
- * This {@code MolodenskyTransform} class expects ordinate values if the following order and units:
+ * This {@code MolodenskyTransform} class expects ordinate values in the following order and units:
* <ol>
* <li>longitudes in <strong>radians</strong> relative to the prime meridian (usually Greenwich),</li>
* <li>latitudes in <strong>radians</strong>,</li>
- * <li>optionally heights above the ellipsoid, in same units than the source ellipsoids axes.</li>
+ * <li>optionally heights above the ellipsoid, in same units than the source ellipsoid axes.</li>
* </ol>
*
* For converting geographic coordinates in degrees, {@code MolodenskyTransform} instances
@@ -238,65 +149,49 @@ public class MolodenskyTransform extends
final double tX, final double tY, final double tZ,
final boolean isAbridged)
{
- ArgumentChecks.ensureNonNull("source", source);
- ArgumentChecks.ensureNonNull("target", target);
- final DefaultEllipsoid src = DefaultEllipsoid.castOrCopy(source);
- this.isSource3D = isSource3D;
- this.isTarget3D = isTarget3D;
- this.isAbridged = isAbridged;
- this.semiMajor = src.getSemiMajorAxis();
- this.Δa = src.semiMajorAxisDifference(target);
- this.tX = tX;
- this.tY = tY;
- this.tZ = tZ;
-
- final double semiMinor = src.getSemiMinorAxis();
- final double Δf = src.flatteningDifference(target);
- eccentricitySquared = src.getEccentricitySquared();
- Δfmod = isAbridged ? (semiMajor * Δf) + (semiMajor - semiMinor) * (Δa / semiMajor)
- : (semiMinor * Δf);
- /*
- * Copy parameters to the ContextualParameter. Those parameters are not used directly
- * by EllipsoidToCartesian, but we need to store them in case the user asks for them.
- * When both EPSG and OGC parameters exist for equivalent information, we use EPSG ones.
- */
- final Unit<Length> unit = src.getAxisUnit();
- final UnitConverter c = target.getAxisUnit().getConverterTo(unit);
- context = new ContextualParameters(isAbridged ? AbridgedMolodensky.PARAMETERS : Molodensky.PARAMETERS,
- isSource3D ? 4 : 3, isTarget3D ? 4 : 3);
- setEPSG(context, unit, Δf);
- context.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit);
- context.getOrCreate(Molodensky.SRC_SEMI_MINOR).setValue(semiMinor, unit);
- context.getOrCreate(Molodensky.TGT_SEMI_MAJOR).setValue(c.convert(target.getSemiMajorAxis()), unit);
- context.getOrCreate(Molodensky.TGT_SEMI_MINOR).setValue(c.convert(target.getSemiMinorAxis()), unit);
- /*
- * Prepare two affine transforms to be executed before and after this MolodenskyTransform:
- *
- * - A "normalization" transform for converting degrees to radians,
- * - A "denormalization" transform for for converting radians to degrees.
- */
- context.normalizeGeographicInputs(0);
- context.denormalizeGeographicOutputs(0);
+ super(source, isSource3D, target, isTarget3D, tX, tY, tZ, null, isAbridged,
+ isAbridged ? AbridgedMolodensky.PARAMETERS : Molodensky.PARAMETERS);
+ if (!isSource3D && !isTarget3D) {
+ inverse = new MolodenskyTransform2D(this, source, target);
+ } else {
+ inverse = new MolodenskyTransform(this, source, target);
+ }
+ }
+
+ /**
+ * Constructs the inverse of a Molodensky transform.
+ *
+ * @param inverse The transform for which to create the inverse.
+ * @param source The source ellipsoid of the given {@code inverse} transform.
+ * @param target The target ellipsoid of the given {@code inverse} transform.
+ */
+ MolodenskyTransform(final MolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) {
+ super(inverse, source, target, inverse.context.getDescriptor());
+ this.inverse = inverse;
}
/**
- * Sets the "dim" parameter and the EPSG parameters in the given group.
- * The OGC parameters other than "dim" are not set by this method.
+ * Invoked by constructor and by {@link #getParameterValues()} for setting all parameters other than axis lengths.
*
- * @param pg Where to set the parameters.
- * @param unit The unit of measurement to declare.
- * @param Δf The flattening difference to set.
- */
- private void setEPSG(final Parameters pg, final Unit<?> unit, final double Δf) {
- final int dim = getSourceDimensions();
- if (dim == getTargetDimensions()) {
- pg.getOrCreate(Molodensky.DIMENSION).setValue(dim);
+ * @param pg Where to set the parameters.
+ * @param semiMinor Ignored.
+ * @param unit The unit of measurement to declare.
+ * @param Δf The flattening difference to set, or NaN if this method should fetch that value itself.
+ */
+ @Override
+ final void completeParameters(final Parameters pg, final double semiMinor, final Unit<?> unit, double Δf) {
+ if (Double.isNaN(Δf)) {
+ Δf = context.doubleValue(Molodensky.FLATTENING_DIFFERENCE);
}
+ super.completeParameters(pg, semiMinor, unit, Δf);
pg.getOrCreate(Molodensky.TX) .setValue(tX, unit);
pg.getOrCreate(Molodensky.TY) .setValue(tY, unit);
pg.getOrCreate(Molodensky.TZ) .setValue(tZ, unit);
pg.getOrCreate(Molodensky.AXIS_LENGTH_DIFFERENCE).setValue(Δa, unit);
pg.getOrCreate(Molodensky.FLATTENING_DIFFERENCE) .setValue(Δf, Unit.ONE);
+ if (pg != context) {
+ pg.parameter("abridged").setValue(isAbridged); // Only in internal parameters.
+ }
}
/**
@@ -319,7 +214,7 @@ public class MolodenskyTransform extends
* @param tY The geocentric <var>Y</var> translation in same units than the source ellipsoid axes.
* @param tZ The geocentric <var>Z</var> translation in same units than the source ellipsoid axes.
* @param isAbridged {@code true} for the abridged formula, or {@code false} for the complete one.
- * @return The transformation between geographic coordinates.
+ * @return The transformation between geographic coordinates in degrees.
* @throws FactoryException if an error occurred while creating a transform.
*/
public static MathTransform createGeodeticTransformation(final MathTransformFactory factory,
@@ -331,79 +226,14 @@ public class MolodenskyTransform extends
final MolodenskyTransform tr;
if (!isSource3D && !isTarget3D) {
tr = new MolodenskyTransform2D(source, target, tX, tY, tZ, isAbridged);
- tr.inverse = new MolodenskyTransform2D(target, source, -tX, -tY, -tZ, isAbridged);
} else {
tr = new MolodenskyTransform(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged);
- tr.inverse = new MolodenskyTransform(target, isTarget3D, source, isSource3D, -tX, -tY, -tZ, isAbridged);
}
- tr.inverse.inverse = tr;
+ tr.inverse.context.completeTransform(factory, null);
return tr.context.completeTransform(factory, tr);
}
/**
- * Returns the unit of measurement of axis lengths. Current implementation arbitrarily
- * returns the units of {@link #Δa} (this may change in any future SIS version).
- */
- private Unit<?> getLinearUnit() {
- return context.getOrCreate(Molodensky.AXIS_LENGTH_DIFFERENCE).getUnit();
- }
-
- /**
- * Returns the parameters used for creating the complete transformation. Those parameters describe a sequence
- * of <cite>normalize</cite> → {@code this} → <cite>denormalize</cite> transforms, <strong>not</strong>
- * including {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes axis swapping}.
- * Those parameters are used for formatting <cite>Well Known Text</cite> (WKT) and error messages.
- *
- * @return The parameters values for the sequence of
- * <cite>normalize</cite> → {@code this} → <cite>denormalize</cite> transforms.
- */
- @Override
- protected ContextualParameters getContextualParameters() {
- return context;
- }
-
- /**
- * Returns a copy of internal parameter values of this {@code MolodenskyTransform}.
- * The returned group contains parameter values for the eccentricity and the shift among others.
- *
- * <div class="note"><b>Note:</b>
- * this method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
- * since the isolation of non-linear parameters in this class is highly implementation dependent.
- * Most GIS applications will instead be interested in the {@linkplain #getContextualParameters()
- * contextual parameters}.</div>
- *
- * @return A copy of the internal parameter values for this transform.
- */
- @Debug
- @Override
- public ParameterValueGroup getParameterValues() {
- final Parameters pg = Parameters.castOrWrap(getParameterDescriptors().createValue());
- final Unit<?> unit = getLinearUnit();
- setEPSG(pg, unit, context.doubleValue(Molodensky.FLATTENING_DIFFERENCE));
- pg.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit);
- pg.getOrCreate(MapProjection.ECCENTRICITY).setValue(sqrt(eccentricitySquared));
- pg.parameter("abridged").setValue(isAbridged);
- return pg;
- }
-
- /**
- * Returns a description of the internal parameters of this {@code MolodenskyTransform} transform.
- * The returned group contains parameter descriptors for the number of dimensions and the eccentricity.
- *
- * @return A description of the internal parameters.
- */
- @Debug
- @Override
- public ParameterDescriptorGroup getParameterDescriptors() {
- synchronized (MolodenskyTransform.class) {
- if (DESCRIPTOR == null) {
- DESCRIPTOR = Molodensky.internal();
- }
- return DESCRIPTOR;
- }
- }
-
- /**
* Returns {@code true} if this transform is the identity one.
* Molodensky transform is considered identity (minus rounding errors) if:
*
@@ -422,49 +252,6 @@ public class MolodenskyTransform extends
}
/**
- * Gets the dimension of input points.
- *
- * @return The input dimension, which is 2 or 3.
- */
- @Override
- public final int getSourceDimensions() {
- return isSource3D ? 3 : 2;
- }
-
- /**
- * Gets the dimension of output points.
- *
- * @return The output dimension, which is 2 or 3.
- */
- @Override
- public final int getTargetDimensions() {
- return isTarget3D ? 3 : 2;
- }
-
- /**
- * Computes the derivative at the given location.
- * This method relaxes a little bit the {@code MathTransform} contract by accepting two- or three-dimensional
- * points even if the number of dimensions does not match the {@link #getSourceDimensions()} or
- * {@link #getTargetDimensions()} values.
- *
- * @param point The coordinate point where to evaluate the derivative.
- * @return The derivative at the specified point (never {@code null}).
- * @throws TransformException if the derivative can not be evaluated at the specified point.
- */
- @Override
- public Matrix derivative(final DirectPosition point) throws TransformException {
- final int dim = point.getDimension();
- final boolean withHeight;
- final double h;
- switch (dim) {
- default: throw mismatchedDimension("point", getSourceDimensions(), dim);
- case 3: withHeight = true; h = point.getOrdinate(2); break;
- case 2: withHeight = false; h = 0; break;
- }
- return transform(point.getOrdinate(0), point.getOrdinate(1), h, withHeight, null, 0, withHeight, true);
- }
-
- /**
* Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS,
* and optionally returns the derivative at that location.
*
@@ -478,133 +265,7 @@ public class MolodenskyTransform extends
final boolean derivate) throws TransformException
{
return transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0,
- isSource3D, dstPts, dstOff, isTarget3D, derivate);
- }
-
- /**
- * Implementation of {@link #transform(double[], int, double[], int, boolean)} with possibility
- * to override whether the source and target coordinates are two- or three-dimensional.
- *
- * @param λ Longitude (radians).
- * @param φ Latitude (radians).
- * @param h Height above the ellipsoid in unit of semi-major axis.
- * @param dstPts The array into which the transformed coordinate is returned.
- * May be {@code null} if only the derivative matrix is desired.
- * @param dstOff The offset to the location of the transformed point that is stored in the destination array.
- * @param derivate {@code true} for computing the derivative, or {@code false} if not needed.
- * @throws TransformException if a point can not be transformed.
- */
- private Matrix transform(final double λ, final double φ, final double h, final boolean isSource3D,
- final double[] dstPts, int dstOff, final boolean isTarget3D,
- final boolean derivate) throws TransformException
- {
- /*
- * Abridged Molodensky formulas from EPSG guidance note:
- *
- * ν = a / √(1 - ℯ²⋅sin²φ) : radius of curvature in the prime vertical
- * ρ = a⋅(1 – ℯ²) / (1 – ℯ²⋅sin²φ)^(3/2) : radius of curvature in the meridian
- * Δλ″ = (-tX⋅sinλ + tY⋅cosλ) / (ν⋅cosφ⋅sin1″)
- * Δφ″ = (-tX⋅sinφ⋅cosλ - tY⋅sinφ⋅sinλ + tZ⋅cosφ + [a⋅Δf + f⋅Δa]⋅sin(2φ)) / (ρ⋅sin1″)
- * Δh = tX⋅cosφ⋅cosλ + tY⋅cosφ⋅sinλ + tZ⋅sinφ + (a⋅Δf + f⋅Δa)⋅sin²φ - Δa
- *
- * we set:
- *
- * dfm = (a⋅Δf + f⋅Δa) in abridged case (b⋅Δf in non-abridged case)
- * sin(2φ) = 2⋅sin(φ)⋅cos(φ)
- */
- final double sinλ = sin(λ);
- final double cosλ = cos(λ);
- final double sinφ = sin(φ);
- final double cosφ = cos(φ);
- final double sin2φ = sinφ * sinφ;
- final double ν2den = 1 - eccentricitySquared*sin2φ; // Square of the denominator of ν
- final double νden = sqrt(ν2den); // Denominator of ν
- final double ρden = ν2den * νden; // Denominator of ρ
- double ρ = semiMajor * (1 - eccentricitySquared) / ρden; // Other notation: Rm = ρ
- double ν = semiMajor / νden; // Other notation: Rn = ν
- double t = Δfmod * 2; // A term in the calculation of Δφ
- if (!isAbridged) {
- ρ += h;
- ν += h;
- t = t*(0.5/νden + 0.5/ρden) // = Δf⋅[ν⋅(b/a) + ρ⋅(a/b)] (without the +h in ν and ρ)
- + Δa*eccentricitySquared/νden; // = Δa⋅[ℯ²⋅ν/a]
- }
- final double spcλ = tY*sinλ + tX*cosλ; // "spc" stands for "sin plus cos"
- final double cmsλ = tY*cosλ - tX*sinλ; // "cms" stands for "cos minus sin"
- final double cmsφ = (tZ + t*sinφ)*cosφ - spcλ*sinφ;
- final double scaleX = ANGULAR_SCALE / (ν*cosφ);
- final double scaleY = ANGULAR_SCALE / ρ;
- if (dstPts != null) {
- dstPts[dstOff++] = λ + (cmsλ * scaleX);
- dstPts[dstOff++] = φ + (cmsφ * scaleY);
- if (isTarget3D) {
- double t1 = Δfmod * sin2φ; // A term in the calculation of Δh
- double t2 = Δa;
- if (!isAbridged) {
- t1 /= νden; // = Δf⋅(b/a)⋅ν⋅sin²φ
- t2 *= νden; // = Δa⋅(a/ν)
- }
- dstPts[dstOff++] = h + spcλ*cosφ + tZ*sinφ + t1 - t2;
- }
- }
- if (!derivate) {
- return null;
- }
- /*
- * At this point the (Abridged) Molodensky transformation is finished.
- * Code below this point is only for computing the derivative, if requested.
- * Note: variable names do not necessarily tell all the terms that they contain.
- */
- final Matrix matrix = Matrices.createDiagonal(getTargetDimensions(), getSourceDimensions());
- final double sinφcosφ = sinφ * cosφ;
- final double dν = eccentricitySquared*sinφcosφ / ν2den;
- final double dν3ρ = 3*dν * (1 - eccentricitySquared) / ν2den;
- // double dXdλ = spcλ;
- final double dYdλ = cmsλ * sinφ;
- final double dZdλ = cmsλ * cosφ;
- double dXdφ = dYdλ / cosφ;
- double dYdφ = -tZ*sinφ - cosφ*spcλ + t*(1 - 2*sin2φ);
- double dZdφ = tZ*cosφ - sinφ*spcλ;
- if (isAbridged) {
- /*
- * Δfmod = (a⋅Δf) + (f⋅Δa)
- * t = 2⋅Δfmod
- * dXdh = 0 so no need to set the matrix element.
- * dYdh = 0 so no need to set the matrix element.
- */
- dXdφ -= cmsλ * dν;
- dYdφ -= cmsφ * dν3ρ;
- dZdφ += t*cosφ*sinφ;
- } else {
- /*
- * Δfmod = b⋅Δf
- * t = Δf⋅[ν⋅(b/a) + ρ⋅(a/b)] (real ν and ρ, without + h)
- * ν is actually ν + h
- * ρ is actually ρ + h
- */
- final double dρ = dν3ρ * νden * (semiMajor / ρ); // Reminder: that ρ contains a h term.
- dXdφ -= dν * cmsλ * semiMajor / (νden*ν); // Reminder: that ν contains a h term.
- dYdφ -= dρ * dZdφ - (Δfmod*(dν*2/(1 - eccentricitySquared) + (1 + 1/ν2den)*(dν - dρ))
- + Δa*(dν + 1)*eccentricitySquared) * sinφcosφ / νden;
- if (isSource3D) {
- final double dXdh = cmsλ / ν;
- final double dYdh = -cmsφ / ρ;
- matrix.setElement(0, 2, -dXdh * scaleX);
- matrix.setElement(1, 2, +dYdh * scaleY);
- }
- final double t1 = Δfmod * (dν*sin2φ + 2*sinφcosφ);
- final double t2 = Δa * dν;
- dZdφ += t1/νden + t2*νden;
- }
- matrix.setElement(0, 0, 1 - spcλ * scaleX);
- matrix.setElement(1, 1, 1 + dYdφ * scaleY);
- matrix.setElement(0, 1, + dXdφ * scaleX);
- matrix.setElement(1, 0, - dYdλ * scaleY);
- if (isTarget3D) {
- matrix.setElement(2, 0, dZdλ);
- matrix.setElement(2, 1, dZdφ);
- }
- return matrix;
+ dstPts, dstOff, tX, tY, tZ, null, derivate);
}
/**
@@ -650,9 +311,9 @@ public class MolodenskyTransform extends
}
}
/*
- * The code in the following loop is basically a copy-and-paste of the code in the above
- * transform(λ, φ, h, isSource3D, dstPts, dstOff, isTarget3D, false) method, but without the
- * code for computing the derivative matrix.
+ * The code in the following loop is basically a copy-and-paste of the code in the
+ * MolodenskyFormula.transform(λ, φ, h, …) method, but without derivative matrix
+ * computation and without support for interpolation of (tX,tY,tZ) values in a grid.
*/
while (--numPts >= 0) {
final double λ = srcPts[srcOff++];
@@ -671,17 +332,18 @@ public class MolodenskyTransform extends
if (!isAbridged) {
ρ += h;
ν += h;
- t = t*(0.5/νden + 0.5/ρden) + Δa*eccentricitySquared/νden;
+ t = t*(0.5/νden + 0.5/ρden) // = Δf⋅[ν⋅(b/a) + ρ⋅(a/b)] (without the +h in ν and ρ)
+ + Δa*eccentricitySquared/νden; // = Δa⋅[ℯ²⋅ν/a]
}
final double spcλ = tY*sinλ + tX*cosλ;
dstPts[dstOff++] = λ + ANGULAR_SCALE * (tY*cosλ - tX*sinλ) / (ν*cosφ);
dstPts[dstOff++] = φ + ANGULAR_SCALE * ((t*cosφ - spcλ)*sinφ + tZ*cosφ) / ρ;
if (isTarget3D) {
- t = Δfmod * sin2φ;
+ t = Δfmod * sin2φ; // A term in the calculation of Δh
double d = Δa;
if (!isAbridged) {
- t /= νden;
- d *= νden;
+ t /= νden; // = Δf⋅(b/a)⋅ν⋅sin²φ
+ d *= νden; // = Δa⋅(a/ν)
}
dstPts[dstOff++] = h + spcλ*cosφ + tZ*sinφ + t - d;
}
@@ -717,46 +379,25 @@ public class MolodenskyTransform extends
}
/**
- * {@inheritDoc}
+ * Returns a description of the internal parameters of this {@code MolodenskyTransform} transform.
+ * The returned group contains parameter descriptors for the number of dimensions and the eccentricity.
*
- * @return {@inheritDoc}
- */
- @Override
- protected int computeHashCode() {
- int code = super.computeHashCode() + Numerics.hashCode(
- Double.doubleToLongBits(Δa)
- + Double.doubleToLongBits(Δfmod)
- + 31 * (Double.doubleToLongBits(tX)
- + 31 * (Double.doubleToLongBits(tY)
- + 31 * (Double.doubleToLongBits(tZ)))));
- if (isAbridged) code = ~code;
- return code;
- }
-
- /**
- * Compares the specified object with this math transform for equality.
+ * <div class="note"><b>Note:</b>
+ * this method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
+ * since the isolation of non-linear parameters in this class is highly implementation dependent.
+ * Most GIS applications will instead be interested in the {@linkplain #getContextualParameters()
+ * contextual parameters}.</div>
*
- * @return {@inheritDoc}
+ * @return A description of the internal parameters.
*/
+ @Debug
@Override
- public boolean equals(final Object object, final ComparisonMode mode) {
- if (object == this) {
- // Slight optimization
- return true;
- }
- if (super.equals(object, mode)) {
- final MolodenskyTransform that = (MolodenskyTransform) object;
- return isSource3D == that.isSource3D
- && isTarget3D == that.isTarget3D
- && isAbridged == that.isAbridged
- && Numerics.equals(tX, that.tX)
- && Numerics.equals(tY, that.tY)
- && Numerics.equals(tZ, that.tZ)
- && Numerics.equals(Δa, that.Δa)
- && Numerics.equals(Δfmod, that.Δfmod)
- && Numerics.equals(semiMajor, that.semiMajor)
- && Numerics.equals(eccentricitySquared, that.eccentricitySquared);
+ public ParameterDescriptorGroup getParameterDescriptors() {
+ synchronized (MolodenskyTransform.class) {
+ if (DESCRIPTOR == null) {
+ DESCRIPTOR = Molodensky.internal();
+ }
+ return DESCRIPTOR;
}
- return false;
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -50,6 +50,17 @@ final class MolodenskyTransform2D extend
}
/**
+ * Constructs the inverse of a 2D transform.
+ *
+ * @param inverse The transform for which to create the inverse.
+ * @param source The source ellipsoid of the given {@code inverse} transform.
+ * @param target The target ellipsoid of the given {@code inverse} transform.
+ */
+ MolodenskyTransform2D(final MolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) {
+ super(inverse, source, target);
+ }
+
+ /**
* Computes the derivative at the given position point.
*/
@Override
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -205,8 +205,8 @@ class ProjectiveTransform extends Abstra
* equal to <code>{@link Matrix#getNumCol}-1</code>. For example, for square matrix of size 4×4, coordinate
* points are three-dimensional and stored in the arrays starting at the specified offset ({@code srcOff}) in
* the order
- * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
- * x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+ * <code>[x₀, y₀, z₀,
+ * x₁, y₁, z₁...,
* x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
*
* @param srcPts The array containing the source point coordinates.
@@ -276,8 +276,8 @@ class ProjectiveTransform extends Abstra
* equal to <code>{@link Matrix#getNumCol()} - 1</code>. For example, for square matrix of size 4×4, coordinate
* points are three-dimensional and stored in the arrays starting at the specified offset ({@code srcOff})
* in the order
- * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
- * x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+ * <code>[x₀, y₀, z₀,
+ * x₁, y₁, z₁...,
* x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
*
* @param srcPts The array containing the source point coordinates.
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -33,10 +33,10 @@ import org.opengis.referencing.operation
* @author Jan Jezek (UWB)
* @author Martin Desruisseaux (Geomatys)
* @since 0.5
- * @version 0.5
+ * @version 0.7
* @module
*/
-final class ProjectiveTransform2D extends ProjectiveTransform implements MathTransform2D {
+final class ProjectiveTransform2D extends ProjectiveTransform implements MathTransform2D, LinearTransform {
/**
* For cross-version compatibility.
*/
@@ -87,9 +87,15 @@ final class ProjectiveTransform2D extend
/**
* Creates the inverse transform of this object.
+ * The inverse shall be linear and two-dimensional.
*/
@Override
- public MathTransform2D inverse() throws NoninvertibleTransformException {
- return (MathTransform2D) super.inverse();
+ public ProjectiveTransform2D inverse() throws NoninvertibleTransformException {
+ final LinearTransform inv = super.inverse();
+ if (inv instanceof ProjectiveTransform2D) {
+ return (ProjectiveTransform2D) inv;
+ } else {
+ return new ProjectiveTransform2D(inv.getMatrix());
+ }
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -184,8 +184,8 @@ final class ScaleTransform extends Abstr
* equal to <code>{@link Matrix#getNumCol}-1</code>. For example, for square matrix of size 4×4, coordinate
* points are three-dimensional and stored in the arrays starting at the specified offset ({@code srcOff}) in
* the order
- * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
- * x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+ * <code>[x₀, y₀, z₀,
+ * x₁, y₁, z₁...,
* x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
*
* @param srcPts The array containing the source point coordinates.
@@ -218,8 +218,8 @@ final class ScaleTransform extends Abstr
* equal to <code>{@link Matrix#getNumCol()} - 1</code>. For example, for square matrix of size 4×4, coordinate
* points are three-dimensional and stored in the arrays starting at the specified offset ({@code srcOff})
* in the order
- * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
- * x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+ * <code>[x₀, y₀, z₀,
+ * x₁, y₁, z₁...,
* x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
*
* @param srcPts The array containing the source point coordinates.
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html [UTF-8] Wed Jan 13 23:25:38 2016
@@ -169,7 +169,7 @@
- <h2>DeormalizeGeographic</h2>
+ <h2>DenormalizeGeographic</h2>
<math display="block" alttext="MathML capable browser required">
<mfenced open="[" close="]">
<mtable>
Modified: sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Wed Jan 13 23:25:38 2016
@@ -3,7 +3,8 @@
org.apache.sis.internal.referencing.provider.Affine
org.apache.sis.internal.referencing.provider.Geographic3Dto2D
org.apache.sis.internal.referencing.provider.GeographicOffsets
-org.apache.sis.internal.referencing.provider.GeographicOffsets3D
+org.apache.sis.internal.referencing.provider.GeographicOffsets2D
+org.apache.sis.internal.referencing.provider.VerticalOffset
org.apache.sis.internal.referencing.provider.LongitudeRotation
org.apache.sis.internal.referencing.provider.GeocentricTranslation
org.apache.sis.internal.referencing.provider.PositionVector7Param
@@ -38,3 +39,6 @@ org.apache.sis.internal.referencing.prov
org.apache.sis.internal.referencing.provider.PolarStereographicNorth
org.apache.sis.internal.referencing.provider.PolarStereographicSouth
org.apache.sis.internal.referencing.provider.ObliqueStereographic
+org.apache.sis.internal.referencing.provider.NTv2
+org.apache.sis.internal.referencing.provider.NADCON
+org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/FormulasTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -17,6 +17,7 @@
package org.apache.sis.internal.referencing;
import org.apache.sis.internal.metadata.ReferencingServices;
+import org.apache.sis.measure.Longitude;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -28,15 +29,24 @@ import static org.junit.Assert.*;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
- * @version 0.5
+ * @version 0.7
* @module
*/
public final strictfp class FormulasTest extends TestCase {
/**
+ * Verifies the {@link Formulas#LONGITUDE_MAX} constant.
+ */
+ @Test
+ public void verifyLongitudeMax() {
+ assertTrue(Formulas.LONGITUDE_MAX > Longitude.MAX_VALUE);
+ assertTrue(StrictMath.ulp(Formulas.LONGITUDE_MAX) <= Formulas.ANGULAR_TOLERANCE);
+ }
+
+ /**
* Verifies the {@link Formulas#JULIAN_YEAR_LENGTH} constant.
*/
@Test
- public void testConstants() {
+ public void verifyJulianYearLength() {
assertEquals(StrictMath.round(365.25 * 24 * 60 * 60 * 1000), Formulas.JULIAN_YEAR_LENGTH);
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -53,7 +53,8 @@ public final strictfp class AllProviders
return new Class<?>[] {
Affine.class,
GeographicOffsets.class,
- GeographicOffsets3D.class,
+ GeographicOffsets2D.class,
+ VerticalOffset.class,
LongitudeRotation.class,
CoordinateFrameRotation.class,
CoordinateFrameRotation2D.class,
@@ -88,7 +89,10 @@ public final strictfp class AllProviders
PolarStereographicC.class,
PolarStereographicNorth.class,
PolarStereographicSouth.class,
- ObliqueStereographic.class
+ ObliqueStereographic.class,
+ NTv2.class,
+ NADCON.class,
+ FranceGeocentricInterpolation.class
};
}
Copied: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java (from r1724479, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java?p2=sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java&p1=sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java&r1=1724479&r2=1724528&rev=1724528&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -33,8 +33,8 @@ import org.junit.Test;
import static org.opengis.test.Assert.*;
// Branch-dependent imports
-import java.nio.file.Paths;
-import java.nio.file.Path;
+import org.apache.sis.internal.jdk7.Paths;
+import org.apache.sis.internal.jdk7.Path;
import org.apache.sis.internal.jdk8.JDK8;
@@ -145,8 +145,11 @@ public final strictfp class FranceGeocen
assertNotNull("Test file \"" + TEST_FILE + "\" not found.", url);
final Path file = Paths.get(url.toURI());
final DatumShiftGridFile.Float<Angle,Length> grid;
- try (final BufferedReader in = JDK8.newBufferedReader(file)) {
+ final BufferedReader in = JDK8.newBufferedReader(file);
+ try {
grid = FranceGeocentricInterpolation.load(in, file);
+ } finally {
+ in.close();
}
assertEquals("cellPrecision", 0.005, grid.getCellPrecision(), STRICT);
assertEquals("getCellMean", 168.2587, grid.getCellMean(0), 0.0001);
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeocentricTranslationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeocentricTranslationTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeocentricTranslationTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeocentricTranslationTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -16,18 +16,23 @@
*/
package org.apache.sis.internal.referencing.provider;
+import java.util.Arrays;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.referencing.operation.TransformException;
import org.opengis.test.ToleranceModifier;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.referencing.datum.HardCodedDatum;
+import org.apache.sis.referencing.operation.matrix.Matrix4;
import org.apache.sis.referencing.operation.transform.CoordinateDomain;
+import org.apache.sis.referencing.operation.transform.EllipsoidToCentricTransform;
import org.apache.sis.referencing.operation.transform.LinearTransform;
import org.apache.sis.referencing.operation.transform.MathTransformTestCase;
import org.apache.sis.test.DependsOnMethod;
@@ -35,7 +40,7 @@ import org.apache.sis.test.DependsOn;
import org.junit.Test;
import static java.lang.StrictMath.toRadians;
-import static org.junit.Assert.*;
+import static org.opengis.test.Assert.*;
/**
@@ -55,6 +60,12 @@ import static org.junit.Assert.*;
})
public final strictfp class GeocentricTranslationTest extends MathTransformTestCase {
/**
+ * Geocentric translation parameters for transforming a point in the North Sea from WGS84 to ED50.
+ * They are the parameters to use for transformation of the point given by {@link #samplePoint(int)}.
+ */
+ public static final double TX = 84.87, TY = 96.49, TZ = 116.95;
+
+ /**
* Returns the sample point for a step in the example given by the EPSG guidance note.
*
* <blockquote><b>Source:</b>
@@ -138,6 +149,41 @@ public final strictfp class GeocentricTr
}
/**
+ * Creates a datum shift operation without using the provider. This method is equivalent to the
+ * <cite>"Geocentric translations (geog3D domain)"</cite> method (EPSG:1035), but the transform
+ * steps are created without the use of any {@link ParameterValueGroup}. This way to create the
+ * datum shift is provided for better separation of aspects being tested.
+ *
+ * @param factory The factory to use for creating the transforms.
+ * @param source The source ellipsoid.
+ * @param target The target ellipsoid.
+ * @param tX Geocentric translation on the X axis.
+ * @param tY Geocentric translation on the Y axis.
+ * @param tZ Geocentric translation on the Z axis.
+ * @return Transform performing the datum shift.
+ * @throws FactoryException if an error occurred while creating the transform.
+ * @throws NoninvertibleTransformException if an error occurred while creating the transform.
+ *
+ * @see #testGeographicDomain()
+ */
+ public static MathTransform createDatumShiftForGeographic3D(
+ final MathTransformFactory factory,
+ final Ellipsoid source, final Ellipsoid target,
+ final double tX, final double tY, final double tZ)
+ throws FactoryException, NoninvertibleTransformException
+ {
+ final Matrix4 translation = new Matrix4();
+ translation.m03 = tX;
+ translation.m13 = tY;
+ translation.m23 = tZ;
+ final MathTransform step1 = EllipsoidToCentricTransform.createGeodeticConversion(factory, source, true);
+ final MathTransform step3 = EllipsoidToCentricTransform.createGeodeticConversion(factory, target, true).inverse();
+ final MathTransform step2 = factory.createAffineTransform(translation);
+ return factory.createConcatenatedTransform(step1,
+ factory.createConcatenatedTransform(step2, step3));
+ }
+
+ /**
* Creates a "Geographic 2D to 3D → Geocentric → Affine → Geographic → Geographic 3D to 2D" chain
* using EPSG or OGC standard operation methods and parameters. This is used for integration tests.
*
@@ -149,17 +195,21 @@ public final strictfp class GeocentricTr
final Parameters values = Parameters.castOrWrap(factory.getDefaultParameters("Geocentric translations (geog2D domain)"));
setTranslation(values);
setEllipsoids(values, CommonCRS.WGS84.ellipsoid(), CommonCRS.ED50.ellipsoid());
- return Geographic3Dto2DTest.createDatumShiftForGeographic2D(factory,
- new GeocentricTranslation().createMathTransform(factory, values), values);
+ final MathTransform gt = new GeocentricTranslation().createMathTransform(factory, values);
+ assertFalse("isIdentity", gt.isIdentity());
+ assertEquals("sourceDimensions", 3, gt.getSourceDimensions());
+ assertEquals("targetDimensions", 3, gt.getTargetDimensions());
+ assertInstanceOf("Geocentric translation", LinearTransform.class, gt);
+ return Geographic3Dto2DTest.createDatumShiftForGeographic2D(factory, gt, values);
}
/**
* Sets the translation parameters in the given parameter value group.
*/
private static void setTranslation(final ParameterValueGroup values) {
- values.parameter("X-axis translation").setValue( 84.87);
- values.parameter("Y-axis translation").setValue( 96.49);
- values.parameter("Z-axis translation").setValue(116.95);
+ values.parameter("X-axis translation").setValue(TX);
+ values.parameter("Y-axis translation").setValue(TY);
+ values.parameter("Z-axis translation").setValue(TZ);
}
/**
@@ -217,6 +267,39 @@ public final strictfp class GeocentricTr
}
/**
+ * Tests the point used in {@link FranceGeocentricInterpolationTest}. We use this test for making sure
+ * that we get the expected value when using the real geocentric translation method. This test will be
+ * completed by an equivalent test in {@code MolodenskyTransformTest} for verifying the quality of our
+ * approximation.
+ *
+ * @throws FactoryException if an error occurred while creating the transform.
+ * @throws TransformException if transformation of a point failed.
+ *
+ * @see org.apache.sis.referencing.operation.transform.MolodenskyTransformTest#testFranceGeocentricInterpolationPoint()
+ */
+ @Test
+ public void testFranceGeocentricInterpolationPoint() throws FactoryException, TransformException {
+ transform = createDatumShiftForGeographic3D(DefaultFactories.forBuildin(MathTransformFactory.class),
+ HardCodedDatum.NTF.getEllipsoid(),
+ CommonCRS.ETRS89.ellipsoid(),
+ -FranceGeocentricInterpolation.TX,
+ -FranceGeocentricInterpolation.TY,
+ -FranceGeocentricInterpolation.TZ);
+
+ final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres
+ derivativeDeltas = new double[] {delta, delta, 100}; // (Δλ, Δφ, Δh)
+ tolerance = FranceGeocentricInterpolationTest.ANGULAR_TOLERANCE;
+ zTolerance = 0.005; // Half the precision of the target[2] value set below.
+ zDimension = new int[] {2};
+
+ final double[] source = Arrays.copyOf(FranceGeocentricInterpolationTest.samplePoint(1), 3);
+ final double[] expected = Arrays.copyOf(FranceGeocentricInterpolationTest.samplePoint(2), 3);
+ expected[2] = 43.15; // Anti-regression (this value is not provided in NTG_88 guidance note).
+ verifyTransform(source, expected);
+ validate();
+ }
+
+ /**
* Tests conversion of random points.
*
* @throws FactoryException if an error occurred while creating the transform.
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -83,6 +83,8 @@ public final strictfp class Geographic3D
static MathTransform createDatumShiftForGeographic2D(final MathTransformFactory factory,
final MathTransform affine, final Parameters pv) throws FactoryException
{
+ assertEquals("sourceDimensions", 3, affine.getSourceDimensions());
+ assertEquals("targetDimensions", 3, affine.getTargetDimensions());
/*
* Create a "Geographic to Geocentric" conversion with ellipsoid axis length units converted to metres
* (the unit implied by SRC_SEMI_MAJOR) because it is the unit of Bursa-Wolf parameters that we created above.
@@ -91,12 +93,19 @@ public final strictfp class Geographic3D
step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.SRC_SEMI_MAJOR));
step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.SRC_SEMI_MINOR));
MathTransform toGeocentric = factory.createParameterizedTransform(step);
+ assertEquals("sourceDimensions", 3, toGeocentric.getSourceDimensions());
+ assertEquals("targetDimensions", 3, toGeocentric.getTargetDimensions());
+
final MathTransform reduce = factory.createParameterizedTransform(factory.getDefaultParameters("Geographic3D to 2D conversion"));
+ assertEquals("sourceDimensions", 3, reduce.getSourceDimensions());
+ assertEquals("targetDimensions", 2, reduce.getTargetDimensions());
try {
toGeocentric = factory.createConcatenatedTransform(reduce.inverse(), toGeocentric);
} catch (NoninvertibleTransformException e) {
throw new FactoryException(e);
}
+ assertEquals("sourceDimensions", 2, toGeocentric.getSourceDimensions());
+ assertEquals("targetDimensions", 3, toGeocentric.getTargetDimensions());
/*
* Create a "Geocentric to Geographic" conversion with ellipsoid axis length units converted to metres
* because this is the unit of the Geocentric CRS used above.
@@ -105,7 +114,12 @@ public final strictfp class Geographic3D
step.getOrCreate(MapProjection.SEMI_MAJOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.TGT_SEMI_MAJOR));
step.getOrCreate(MapProjection.SEMI_MINOR).setValue(pv.doubleValue(GeocentricAffineBetweenGeographic.TGT_SEMI_MINOR));
MathTransform toGeographic = factory.createParameterizedTransform(step);
+ assertEquals("sourceDimensions", 3, toGeographic.getSourceDimensions());
+ assertEquals("targetDimensions", 3, toGeographic.getTargetDimensions());
+
toGeographic = factory.createConcatenatedTransform(toGeographic, reduce);
+ assertEquals("sourceDimensions", 3, toGeographic.getSourceDimensions());
+ assertEquals("targetDimensions", 2, toGeographic.getTargetDimensions());
/*
* The Geocentric → Affine → Geographic chain.
*/
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -16,17 +16,24 @@
*/
package org.apache.sis.internal.referencing.provider;
+import javax.measure.unit.NonSI;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
-import org.opengis.test.referencing.TransformTestCase;
import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
+
+// Test dependencies
+import org.opengis.test.referencing.TransformTestCase;
+import org.apache.sis.referencing.cs.HardCodedCS;
import org.apache.sis.test.DependsOn;
import org.junit.Test;
/**
- * Tests the {@link GeographicOffsets} and {@link GeographicOffsets3D} classes.
+ * Tests the {@link GeographicOffsets}, {@link GeographicOffsets2D} and {@link VerticalOffset} classes.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.7
@@ -36,26 +43,26 @@ import org.junit.Test;
@DependsOn(AffineTest.class)
public final strictfp class GeographicOffsetsTest extends TransformTestCase {
/**
- * Tests {@code GeographicOffsets.createMathTransform(…)}.
+ * Tests {@code GeographicOffsets2D.createMathTransform(…)}.
* This test uses the sample point given in §2.4.4.3 of EPSG guide (April 2015).
*
* @throws FactoryException should never happen.
* @throws TransformException should never happen.
*/
@Test
- public void testCreateMathTransform2D() throws FactoryException, TransformException {
+ public void testGeographicOffsets2D() throws FactoryException, TransformException {
testCreateMathTransform(new GeographicOffsets());
}
/**
- * Tests {@code GeographicOffsets3D.createMathTransform(…)}.
+ * Tests {@code GeographicOffsets.createMathTransform(…)}.
*
* @throws FactoryException should never happen.
* @throws TransformException should never happen.
*/
@Test
- public void testCreateMathTransform3D() throws FactoryException, TransformException {
- testCreateMathTransform(new GeographicOffsets3D());
+ public void testGeographicOffsets3D() throws FactoryException, TransformException {
+ testCreateMathTransform(new GeographicOffsets2D());
}
/**
@@ -77,4 +84,63 @@ public final strictfp class GeographicOf
target[0] = 23 + (48 + 16.515 /60) /60; // 23°48′16.515″E
verifyTransform(source, target);
}
+
+ /**
+ * Tests {@code VerticalOffset.createMathTransform(…)}.
+ * This test uses the sample point given in §2.4.2.1 of EPSG guide (April 2015)
+ * for the <cite>"KOC CD height to KOC WD depth (ft) (1)"</cite> transformation (EPSG:5453).
+ *
+ * <p><b>IMPORTANT:</b> since the source and target axis directions are opposite, the input coordinate
+ * need to be multiplied by -1 <strong>before</strong> the operation is applied. This order is required
+ * for consistency with the sign of <cite>"Vertical Offset"</cite> parameter value.</p>
+ *
+ * @throws FactoryException should never happen.
+ * @throws TransformException should never happen.
+ */
+ @Test
+ public void testVerticalOffset() throws FactoryException, TransformException {
+ final VerticalOffset provider = new VerticalOffset();
+ final ParameterValueGroup pv = provider.getParameters().createValue();
+ pv.parameter("Vertical Offset").setValue(15.55, NonSI.FOOT);
+ transform = provider.createMathTransform(null, pv);
+ tolerance = Formulas.LINEAR_TOLERANCE;
+ final double[] source = new double[transform.getSourceDimensions()];
+ final double[] target = new double[transform.getTargetDimensions()];
+ source[0] = -2.55; // 2.55 metres up, sign reversed in order to match target axis direction.
+ target[0] = 7.18 * 0.3048; // 7.18 feet down.
+ verifyTransform(source, target);
+ }
+
+ /**
+ * Tests {@code VerticalOffset.createMathTransform(…)} indirectly, through a call to the math transform factory
+ * with the source and target coordinate systems specified. The intend of this test is to verify that the change
+ * of axis direction is properly handled, given source CRS axis direction up and target CRS axis direction down.
+ *
+ * @throws FactoryException if an error occurred while creating the transform.
+ * @throws TransformException should never happen.
+ */
+ @Test
+ public void testCreateWithContext() throws FactoryException, TransformException {
+ final DefaultMathTransformFactory factory = DefaultFactories.forBuildin(
+ MathTransformFactory.class, DefaultMathTransformFactory.class);
+ final ParameterValueGroup pv = factory.getDefaultParameters("Vertical Offset");
+ pv.parameter("Vertical Offset").setValue(15.55, NonSI.FOOT);
+ /*
+ * Now create the MathTransform. But at the difference of the above testVerticalOffset() method,
+ * we supply information about axis directions. The operation parameter shall have the same sign
+ * than in the EPSG database (which is positive), and the source and target ordinates shall have
+ * the same sign than in the EPSG example (positive too). However we do not test unit conversion
+ * in this method (EPSG sample point uses feet units), only axis direction.
+ */
+ final DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
+ context.setSource(HardCodedCS.GRAVITY_RELATED_HEIGHT); // Direction up, in metres.
+ context.setTarget(HardCodedCS.DEPTH); // Direction down, in metres.
+ transform = factory.createParameterizedTransform(pv, context);
+ tolerance = Formulas.LINEAR_TOLERANCE;
+ final double[] source = new double[transform.getSourceDimensions()];
+ final double[] target = new double[transform.getTargetDimensions()];
+ source[0] = 2.55; // 2.55 metres up, same sign than in EPSG example (positive).
+ target[0] = 7.18 * 0.3048; // 7.18 feet down.
+ verifyTransform(source, target);
+ }
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/MapProjectionTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -64,12 +64,12 @@ public final strictfp class MapProjectio
assertParamEquals(null, SEMI_MAJOR, true, it.next());
assertParamEquals(null, SEMI_MINOR, true, it.next());
assertParamEquals("Latitude of 1st standard parallel", STANDARD_PARALLEL_1, true, it.next());
- assertParamEquals("Latitude of natural origin", "latitude_of_origin", false, it.next());
+ assertParamEquals("Latitude of natural origin", LATITUDE_OF_ORIGIN, false, it.next());
assertParamEquals("Longitude of natural origin", CENTRAL_MERIDIAN, true, it.next());
assertParamEquals("False easting", FALSE_EASTING, true, it.next());
assertParamEquals("False northing", FALSE_NORTHING, true, it.next());
assertFalse(it.hasNext());
- assertIsForcedToZero((ParameterDescriptor<?>) Equirectangular.PARAMETERS.descriptor("latitude_of_origin"));
+ assertIsForcedToZero((ParameterDescriptor<?>) Equirectangular.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
}
/**
@@ -82,13 +82,13 @@ public final strictfp class MapProjectio
assertParamEquals("Mercator (variant A)", "Mercator_1SP", true, Mercator1SP.PARAMETERS);
assertParamEquals(null, SEMI_MAJOR, true, it.next());
assertParamEquals(null, SEMI_MINOR, true, it.next());
- assertParamEquals("Latitude of natural origin", "latitude_of_origin", true, it.next());
+ assertParamEquals("Latitude of natural origin", LATITUDE_OF_ORIGIN, true, it.next());
assertParamEquals("Longitude of natural origin", CENTRAL_MERIDIAN, true, it.next());
assertParamEquals("Scale factor at natural origin", SCALE_FACTOR, true, it.next());
assertParamEquals("False easting", FALSE_EASTING, true, it.next());
assertParamEquals("False northing", FALSE_NORTHING, true, it.next());
assertFalse(it.hasNext());
- assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor("latitude_of_origin"));
+ assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
}
/**
@@ -102,13 +102,13 @@ public final strictfp class MapProjectio
assertParamEquals(null, SEMI_MAJOR, true, it.next());
assertParamEquals(null, SEMI_MINOR, true, it.next());
assertParamEquals("Latitude of 1st standard parallel", STANDARD_PARALLEL_1, true, it.next());
- assertParamEquals("Latitude of natural origin", "latitude_of_origin", false, it.next());
+ assertParamEquals("Latitude of natural origin", LATITUDE_OF_ORIGIN, false, it.next());
assertParamEquals("Longitude of natural origin", CENTRAL_MERIDIAN, true, it.next());
assertParamEquals(null, SCALE_FACTOR, false, it.next());
assertParamEquals("False easting", FALSE_EASTING, true, it.next());
assertParamEquals("False northing", FALSE_NORTHING, true, it.next());
assertFalse(it.hasNext());
- assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor("latitude_of_origin"));
+ assertIsForcedToZero((ParameterDescriptor<?>) Mercator1SP.PARAMETERS.descriptor(LATITUDE_OF_ORIGIN));
}
/**
Copied: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java (from r1724479, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java?p2=sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java&p1=sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java&r1=1724479&r2=1724528&rev=1724528&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -35,8 +35,8 @@ import org.junit.Test;
import static org.opengis.test.Assert.*;
// Branch-dependent imports
-import java.nio.file.Path;
-import java.nio.file.Paths;
+import org.apache.sis.internal.jdk7.Path;
+import org.apache.sis.internal.jdk7.Paths;
import org.apache.sis.internal.jdk8.JDK8;
@@ -234,7 +234,8 @@ public final strictfp class NADCONTest e
{
Envelope envelope = new Envelope2D(null, gridX, gridY, nx - 1, ny - 1);
envelope = Envelopes.transform(grid.getCoordinateToGrid().inverse(), envelope);
- try (final BufferedWriter out = JDK8.newBufferedWriter(file)) {
+ final BufferedWriter out = JDK8.newBufferedWriter(file);
+ try {
out.write("NADCON EXTRACTED REGION\n");
out.write(String.format(Locale.US, "%4d %3d %3d %11.5f %11.5f %11.5f %11.5f %11.5f\n", nx, ny, 1,
envelope.getMinimum(0), envelope.getSpan(0) / (nx - 1),
@@ -246,6 +247,8 @@ public final strictfp class NADCONTest e
}
out.write('\n');
}
+ } finally {
+ out.close();
}
}
}
Copied: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java (from r1724479, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java?p2=sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java&p1=sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java&r1=1724479&r2=1724528&rev=1724528&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -19,28 +19,20 @@ package org.apache.sis.internal.referenc
import java.net.URL;
import java.net.URISyntaxException;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.WritableByteChannel;
-import java.nio.charset.StandardCharsets;
import javax.measure.unit.NonSI;
import javax.measure.quantity.Angle;
import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.referencing.operation.matrix.Matrix3;
-import org.apache.sis.geometry.Envelope2D;
-import org.apache.sis.geometry.Envelopes;
import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.opengis.test.Assert.*;
// Branch-dependent imports
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.Files;
-import java.nio.file.StandardOpenOption;
+import org.apache.sis.internal.jdk7.Path;
+import org.apache.sis.internal.jdk7.Paths;
/**
@@ -164,98 +156,4 @@ public final strictfp class NTv2Test ext
FranceGeocentricInterpolationTest.ANGULAR_TOLERANCE * DatumShiftGridLoader.DEGREES_TO_SECONDS);
assertSame("Grid should be cached.", grid, NTv2.getOrLoad(file));
}
-
-
-
-
- //////////////////////////////////////////////////
- //////// ////////
- //////// TEST FILE CREATION ////////
- //////// ////////
- //////////////////////////////////////////////////
-
- /**
- * Writes a sub-grid of the given grid in pseudo-NTv2 format. This method is used only for creating the test file.
- * The file created by this method is not fully NTv2 compliant (in particular, we do not write complete header),
- * but we take this opportunity for testing {@code NTv2.Loader} capability to be lenient.
- *
- * <p>This method has been executed once for creating the {@code "NTF_R93-extract.gsb"} test file and should not
- * be needed anymore, but we keep it around in case we have new test files to generate. The parameter used for
- * creating the test file are:</p>
- *
- * <ul>
- * <li>{@code gridX} = 72</li>
- * <li>{@code gridY} = 74</li>
- * <li>{@code nx} = 6</li>
- * <li>{@code ny} = 7</li>
- * </ul>
- *
- * This ensure that the grid indices (75.7432814, 78.4451225) is included in the test file.
- * Those grid indices is the location of the (2°25′32.4187″N 48°50′40.2441″W) test point to interpolate.
- *
- * <div class="section">Limitations</div>
- * This method assumes that bounding box and increments have integer values, and that any fractional part
- * is rounding errors. This is usually the case when using the {@code "SECONDS"} unit of measurement.
- * This assumption does not apply to the shift values.
- *
- * @param grid The full grid from which to extract a few values.
- * @param out Where to write the test file.
- * @param gridX Index along the longitude axis of the first cell to write.
- * @param gridY Index along the latitude axis of the first cell to write.
- * @param nx Number of cells to write along the longitude axis.
- * @param ny Number of cells to write along the latitude axis.
- * @throws TransformException if an error occurred while computing the envelope.
- * @throws IOException if an error occurred while writing the test file.
- */
- public static void writeSubGrid(final DatumShiftGridFile<Angle,Angle> grid, final Path out,
- final int gridX, final int gridY, final int nx, final int ny) throws IOException, TransformException
- {
- Envelope envelope = new Envelope2D(null, gridX, gridY, nx - 1, ny - 1);
- envelope = Envelopes.transform(grid.getCoordinateToGrid().inverse(), envelope);
- final ByteBuffer buffer = ByteBuffer.allocate(4096);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- writeString(buffer, "NUM_OREC"); buffer.putInt(5); nextRecord(buffer);
- writeString(buffer, "NUM_SREC"); buffer.putInt(7); nextRecord(buffer);
- writeString(buffer, "NUM_FILE"); buffer.putInt(1); nextRecord(buffer);
- writeString(buffer, "GS_TYPE"); writeString(buffer, "SECONDS");
- writeString(buffer, "VERSION"); writeString(buffer, "SIS_TEST"); // Last overview record.
- writeString(buffer, "S_LAT"); buffer.putDouble(Math.rint( envelope.getMinimum(1)));
- writeString(buffer, "N_LAT"); buffer.putDouble(Math.rint( envelope.getMaximum(1)));
- writeString(buffer, "E_LONG"); buffer.putDouble(Math.rint(-envelope.getMaximum(0))); // Sign reversed.
- writeString(buffer, "W_LONG"); buffer.putDouble(Math.rint(-envelope.getMinimum(0)));
- writeString(buffer, "LAT_INC"); buffer.putDouble(Math.rint( envelope.getSpan(1) / (ny - 1)));
- writeString(buffer, "LONG_INC"); buffer.putDouble(Math.rint( envelope.getSpan(0) / (nx - 1)));
- writeString(buffer, "GS_COUNT"); buffer.putInt(nx * ny); nextRecord(buffer);
- for (int y=0; y<ny; y++) {
- for (int x=0; x<nx; x++) {
- buffer.putFloat((float) grid.getCellValue(1, gridX + x, gridY + y));
- buffer.putFloat((float) grid.getCellValue(0, gridX + x, gridY + y));
- buffer.putFloat(ACCURACY);
- buffer.putFloat(ACCURACY);
- }
- }
- writeString(buffer, "END");
- nextRecord(buffer);
- try (final WritableByteChannel c = Files.newByteChannel(out, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
- buffer.flip();
- c.write(buffer);
- }
- }
-
- /**
- * Writes the given string in the given buffer. It is caller's responsibility to ensure that the
- * string does not occupy more than 8 bytes in US-ASCII encoding.
- */
- private static void writeString(final ByteBuffer buffer, final String keyword) {
- final int upper = buffer.position() + 8; // "8" is the space allowed for strings in NTv2 format.
- buffer.put(keyword.getBytes(StandardCharsets.US_ASCII));
- while (buffer.position() != upper) buffer.put((byte) ' ');
- }
-
- /**
- * Moves the buffer position to the next record.
- */
- private static void nextRecord(final ByteBuffer buffer) {
- buffer.position(((buffer.position() / 16) + 1) * 16); // "16" is the length of records in NTv2 format.
- }
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -1004,12 +1004,12 @@ public final strictfp class GeodeticObje
" • The text contains unknown elements:\n" +
" ‣ “Intruder” in PRIMEM, GEOGCS.\n" +
" ‣ “Ext1” in SPHEROID.\n" +
- " ‣ “Ext2” in SPHEROID.\n", warnings.toString(Locale.US));
+ " ‣ “Ext2” in SPHEROID.", warnings.toString(Locale.US));
assertMultilinesEquals("La lecture de « WGS 84 » a été faite, mais en ignorant certains éléments.\n" +
" • Le texte contient des éléments inconnus :\n" +
" ‣ « Intruder » dans PRIMEM, GEOGCS.\n" +
" ‣ « Ext1 » dans SPHEROID.\n" +
- " ‣ « Ext2 » dans SPHEROID.\n", warnings.toString(Locale.FRANCE));
+ " ‣ « Ext2 » dans SPHEROID.", warnings.toString(Locale.FRANCE));
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java?rev=1724528&r1=1724527&r2=1724528&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java [UTF-8] Wed Jan 13 23:25:38 2016
@@ -19,6 +19,7 @@ package org.apache.sis.parameter;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Collections;
import org.opengis.parameter.GeneralParameterDescriptor;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterDescriptor;
@@ -27,6 +28,7 @@ import org.opengis.parameter.ParameterVa
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.InvalidParameterNameException;
import org.opengis.parameter.InvalidParameterCardinalityException;
+import org.apache.sis.util.ComparisonMode;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
@@ -43,7 +45,7 @@ import static org.opengis.referencing.Id
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.4
- * @version 0.6
+ * @version 0.7
* @module
*/
@DependsOn({
@@ -415,6 +417,26 @@ public final strictfp class DefaultParam
}
/**
+ * Tests {@link #equals(Object, ComparisonMode)}.
+ *
+ * @since 0.7
+ */
+ @Test
+ @DependsOnMethod("testEqualsAndHashCode")
+ public void testEqualsIgnoreMetadata() {
+ final DefaultParameterValueGroup g1 = createGroup(10);
+ final DefaultParameterValueGroup g2 = new DefaultParameterValueGroup(g1.getDescriptor());
+ final List<GeneralParameterValue> values = new ArrayList<GeneralParameterValue>(g1.values());
+ Collections.swap(values, 2, 3);
+ g2.values().addAll(values);
+
+ assertFalse("STRICT", g1.equals(g2, ComparisonMode.STRICT));
+ assertFalse("BY_CONTRACT", g1.equals(g2, ComparisonMode.BY_CONTRACT));
+ assertTrue ("IGNORE_METADATA", g1.equals(g2, ComparisonMode.IGNORE_METADATA));
+ assertTrue ("APPROXIMATIVE", g1.equals(g2, ComparisonMode.APPROXIMATIVE));
+ }
+
+ /**
* Tests {@link DefaultParameterValueGroup} serialization.
*/
@Test