This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 2b94c39aca000c337ff37b8c09a8e0a801ae00c2
Author: Matthieu_Bastianelli <matthieu.bastiane...@geomatys.com>
AuthorDate: Wed Jul 24 14:33:59 2019 +0200

    feat (referencing) : add some tests for satellite-tracking projections from 
tables 38 and 39 of Snyder's Manual (page 238). Fix the condition of the while 
loop when applying Newton method.
---
 .../referencing/provider/SatelliteTracking.java    |   6 +-
 .../projection/ConicSatelliteTracking.java         | 139 +++++++++---------
 .../projection/CylindricalSatelliteTracking.java   |  44 +++---
 .../projection/ConicSatelliteTrackingTest.java     | 156 +++++++++++++++------
 .../CylindricalSatelliteTrackingTest.java          |  49 +++----
 .../sis/test/suite/ReferencingTestSuite.java       |   2 +
 6 files changed, 236 insertions(+), 160 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/SatelliteTracking.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/SatelliteTracking.java
index 6784123..787b404 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/SatelliteTracking.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/SatelliteTracking.java
@@ -151,7 +151,7 @@ public class SatelliteTracking extends MapProjection {
         SATELLITE_ORBIT_INCLINATION = builder
                 .addName("satellite_orbit_inclination")
                 .setDescription("Angle of inclination between the plane of the 
Earth's Equator and the plane of the satellite orbit")
-                .create(0, Units.RADIAN);
+                .create(0, Units.DEGREE);
 
         SATELLITE_ORBITAL_PERIOD = builder
                 .addName("satellite_orbital_period")
@@ -162,7 +162,7 @@ public class SatelliteTracking extends MapProjection {
                 .addName("ascending_node_period")
                 .setDescription("Length of Earth's rotation with respect to 
the precessed ascending node")
                 .createStrictlyPositive(98.884, Units.MINUTE);
-                
+
         PARAMETERS = builder.addName(NAME)
                 .createGroupForMapProjection(CENTRAL_MERIDIAN,
                         STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,
@@ -187,7 +187,7 @@ public class SatelliteTracking extends MapProjection {
     protected NormalizedProjection createProjection(final Parameters 
parameters) throws ParameterNotFoundException {
         ArgumentChecks.ensureNonNull("Parameters", parameters);
 
-        if (parameters.getValue(STANDARD_PARALLEL_2) == 
-parameters.getValue(STANDARD_PARALLEL_1)) { 
+        if (parameters.getValue(STANDARD_PARALLEL_2) == 
-parameters.getValue(STANDARD_PARALLEL_1)) {
             return new 
org.apache.sis.referencing.operation.projection.CylindricalSatelliteTracking(this,
 parameters);
         } else {
             return new 
org.apache.sis.referencing.operation.projection.ConicSatelliteTracking(this, 
parameters);
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTracking.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTracking.java
index f7247df..d650fa2 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTracking.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTracking.java
@@ -34,13 +34,13 @@ import 
org.apache.sis.referencing.operation.transform.ContextualParameters;
 
 /**
  * <cite>Cylindrical Satellite-Tracking projections</cite>.
- * 
+ *
  * <cite>
  * - All groundtracks for satellites orbiting the Earth with the same orbital
  * parameters are shown as straight lines on the map.
  *
  * - Cylindrical {@link CylindricalSatelliteTracking}
- * or conical {@link ConicSatelliteTracking} form available. 
+ * or conical {@link ConicSatelliteTracking} form available.
  *
  * - Neither conformal nor equal-area.
  *
@@ -78,33 +78,35 @@ import 
org.apache.sis.referencing.operation.transform.ContextualParameters;
  * @version 1.0
  */
 public class ConicSatelliteTracking extends NormalizedProjection{
-    
+
     /**
      * {@code SATELLITE_ORBIT_INCLINATION}
      */
     final double i;
-    
+
     /**
      * Coefficients for both cylindrical and conic Satellite-Tracking 
Projection.
      */
     final double cos_i, sin_i, cos2_i, cos_φ1, p2_on_p1;
-    
+
 //    /**
 //     * Radius of the circle radius of the circle to which groundtracks
 //     * are tangent on the map.
 //     */
 //    private final double ρs;
-    
+
     /**
      * Projection Cone's constant.
      */
     private final double n;
-    
+
     /**
-     * Approximation of the Minimum latitude at infinite radius. 
-     * 
+     * Approximation of the Minimum latitude at infinite radius.
+     *
      * Limiting latitude to which the {@code L coefficient}
      * is associated with a particular case {@code L equals -s0/n}.
+     * In such a situation the coefficent ρ computed for transformations
+     * is infinite.
      */
     private final double latitudeLimit;
     /**
@@ -143,11 +145,11 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
 
     /**
      * Constructor for ConicSatelliteTracking.
-     * 
-     * Calculation are based on <cite>28 .SATTELITE-TRACKING PROJECTIONS 
</cite> 
+     *
+     * Calculation are based on <cite>28 .SATTELITE-TRACKING PROJECTIONS 
</cite>
      * in <cite> Map Projections - A Working Manual</cite> By John P. Snyder.
-     * 
-     * @param initializer 
+     *
+     * @param initializer
      */
     ConicSatelliteTracking(final Initializer initializer) {
         super(initializer);
@@ -155,7 +157,7 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
         
//======================================================================
         // Common for both cylindrical and conic sattelite tracking 
projections :
         
//======================================================================
-        i        = 
toRadians(initializer.getAndStore(SATELLITE_ORBIT_INCLINATION)); // Radian 
input value.
+        i        = 
toRadians(initializer.getAndStore(SATELLITE_ORBIT_INCLINATION));
         cos_i    = cos(i);
         sin_i    = sin(i);
         cos2_i   = cos_i * cos_i;
@@ -164,11 +166,11 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
         final double φ1      = 
toRadians(initializer.getAndStore(STANDARD_PARALLEL_1));  //appropriated use of 
toRadians??
         cos_φ1               = cos(φ1);
         final double cos2_φ1 = cos_φ1 * cos_φ1;
-        
+
         
//======================================================================
         // For conic projection :
         //=======================
-        if(!(this instanceof CylindricalSatelliteTracking)) {
+        if (!(this instanceof CylindricalSatelliteTracking)) {
             final double sin_φ1 = sin(φ1);
             final double φ0 = 
toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));   //appropriated use of 
toRadians??
             final double cos_φ0 = cos(φ0);
@@ -176,13 +178,13 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
             final double sin_φ0 = sin(φ0);
             final double φ2 = 
toRadians(initializer.getAndStore(STANDARD_PARALLEL_2));   //appropriated use 
of toRadians??
 
-//            final DoubleUnaryOperator computeFn = (cos2_φn) -> 
atan((p2_on_p1 * cos2_φn - cos_i) / sqrt(cos2_φn - cos2_i)); // eq.28-9 in 
Snyder 
+//            final DoubleUnaryOperator computeFn = (cos2_φn) -> 
atan((p2_on_p1 * cos2_φn - cos_i) / sqrt(cos2_φn - cos2_i)); // eq.28-9 in 
Snyder
 //            final double F0 = computeFn.applyAsDouble(cos2_φ0);
 //            final double F1 = computeFn.applyAsDouble(cos2_φ1);
-//            final DoubleUnaryOperator computedλn = (sin_φn) -> -asin(sin_φn 
/ sin_i); // eq.28-2a in Snyder 
+//            final DoubleUnaryOperator computedλn = (sin_φn) -> -asin(sin_φn 
/ sin_i); // eq.28-2a in Snyder
 //            final double dλ0 = computedλn.applyAsDouble(sin_φ0);
 //            final double dλ1 = computedλn.applyAsDouble(sin_φ1);
-//            final DoubleUnaryOperator computeλtn = (dλn) -> atan(tan(dλn) * 
cos_i); // eq.28-3a in Snyder 
+//            final DoubleUnaryOperator computeλtn = (dλn) -> atan(tan(dλn) * 
cos_i); // eq.28-3a in Snyder
 //            final double λt0 = computeλtn.applyAsDouble(dλ0);
 //            final double λt1 = computeλtn.applyAsDouble(dλ1);
 
@@ -203,10 +205,10 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
             final double L0 = λt0 - p2_on_p1 * dλ0;
             final double L1 = λt1 - p2_on_p1 * dλ1;
 
-            if (φ1 == PI / 2 - i) { //tracking limit
+            if (φ1 == PI - i) { //tracking limit computed as 180 - i from 
Snyder's manual p.238
                 final double factor = (p2_on_p1 * cos_i - 1);
                 final double factor2 = factor * factor;
-                n = sin_i / (factor2); //eq. 28-18 in Snyder 
+                n = sin_i / (factor2); //eq. 28-18 in Snyder
             } else if (φ2 != φ1) {
                 final double cos_φ2 = cos(φ2);
                 final double cos2_φ2 = cos_φ2 * cos_φ2;
@@ -219,10 +221,10 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
                 final double F2 = computeFn(cos2_φ2);
                 n = (F2 - F1) / (L2 - L1);
             } else {
-                n = sin_φ1 * (p2_on_p1 * (2 * cos2_i - cos2_φ1) - cos_i) / 
(p2_on_p1 * cos2_φ1 - cos_i); //eq. 28-17 in Snyder 
+                n = sin_φ1 * (p2_on_p1 * (2 * cos2_i - cos2_φ1) - cos_i) / 
(p2_on_p1 * cos2_φ1 - cos_i); //eq. 28-17 in Snyder
             }
             s0 = F1 - n * L1;
-            ρ0 = cos_φ1xsin_F1 / (n * sin(n * L0 + s0)); // *R in eq.28-12 in 
Snyder 
+            ρ0 = cos_φ1xsin_F1 / (n * sin(n * L0 + s0)); // *R in eq.28-12 in 
Snyder
 
             //======================== Unsure 
======================================
             // Aim to assess the limit latitude associated with -s0/n L-value.
@@ -234,14 +236,17 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
 //            //Additionally we can compute the radius of the circle to which 
groundtracks
 //            //are tangent on the map :
 //            ρs = cos_φ1xsin_F1 / n; //*R
-            
//======================================================================        
+            
//======================================================================
             /*
          * At this point, all parameters have been processed. Now process to 
their
          * validation and the initialization of (de)normalize affine 
transforms.
              */
             final MatrixSIS normalize = 
context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
             normalize.convertAfter(0, n, null);  //For conic tracking
-        }else{
+
+            final MatrixSIS denormalize = 
context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
+            denormalize.convertBefore(1, 1, ρ0);  //For conic tracking
+        } else {
             n = latitudeLimit = cos_φ1xsin_F1 = s0 = ρ0 = NaN;
             positiveN = false;
         }
@@ -263,58 +268,59 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
      * @throws ProjectionException if the coordinates can not be converted.
      */
     @Override
-    public Matrix transform(double[] srcPts, int srcOff, 
+    public Matrix transform(double[] srcPts, int srcOff,
                             double[] dstPts, int dstOff,
                             boolean derivate) throws ProjectionException {
-        
+
         final double λ      = srcPts[srcOff];
         final double φ      = srcPts[srcOff + 1];
-        
+
         /*
          * According to the Snyder (page 236) in those cases cannot or should 
not be plotted.
          */
-        if( ((positiveN)&&(φ<=latitudeLimit)) || 
((!positiveN)&&(φ>=latitudeLimit)) ){
+        if ( ((positiveN) && (φ<=latitudeLimit)) || ((!positiveN) && 
(φ>=latitudeLimit)) ){
             throw new 
ProjectionException(Resources.format(Resources.Keys.CanNotTransformCoordinates_2));
         }
-        
+
         final double sin_φ  = sin(φ);
         final double dλ     = -asin(sin_φ / sin_i);
         final double λt     = atan(tan(dλ) * cos_i);
         final double L      = λt - p2_on_p1 * dλ;
-        
+
         /*
          * As {@code latitudeLimit} is an approximation we repeat the test 
here.
          */
-        if( ((positiveN)&&(L<=-s0/n)) || ((!positiveN)&&(L>=-s0/n)) ){
+        if ( ((positiveN) && (L<=-s0/n)) || ((!positiveN) && (L>=-s0/n)) ){
             //TODO if usefull, could we add :
             // latitudeLimit = φ;
             throw new 
ProjectionException(Resources.format(Resources.Keys.CanNotTransformCoordinates_2));
         }
-        
-        final double ρ      = cos_φ1xsin_F1/(n*sin(n*L+s0)); 
+
+        final double ρ      = cos_φ1xsin_F1/(n*sin(n*L+s0));
         final double θ      = λ;      // extracted n
-        
+
         final double sinθ = sin(θ);
         final double cosθ = cos(θ);
         if (dstPts != null) {
             dstPts[dstOff    ] = ρ * sinθ;   // x
-            dstPts[dstOff + 1] = ρ0 - ρ*cosθ;  // y       //TODO : extract ρ0 
when ensuring : λ = λ - λ0;
+//            dstPts[dstOff + 1] = ρ0 - ρ*cosθ;  // y       //TODO : extract 
ρ0 when ensuring : λ = λ - λ0;
+            dstPts[dstOff + 1] = - ρ*cosθ;
         }
-        
+
          if (!derivate) {
             return null;
         }
 
         //=========================TO Resolve =================================
-//        final double dx_dλ = ρ*n*cosθ; 
+//        final double dx_dλ = ρ*n*cosθ;
 //        final double dx_dφ =?;
 //
 //        final double dy_dλ =  ρ*n*sinθ;
 //        final double dy_dφ = ?;
         
//======================================================================
-        
+
         throw new UnsupportedOperationException("Not supported yet."); //To 
change body of generated methods, choose Tools | Templates.
-        
+
         //Additionally we can compute the scale factors :
         // k = ρ*n/cos(φ); // /R
         // h = k*tan(F)/tan(n*L+s0);
@@ -330,41 +336,42 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
     protected void inverseTransform(double[] srcPts, int srcOff,
                                     double[] dstPts, int dstOff)
                                     throws ProjectionException {
-        
+
         final double x   = srcPts[srcOff];
-        final double y   = srcPts[srcOff + 1] - ρ0;
-        
+//        final double y   = srcPts[srcOff + 1] - ρ0;
+        final double y   = srcPts[srcOff + 1];
+
         //TODO : extract - ρ0 : MatrixSIS convertBefore and convertAfter??
-        
-        if((x== 0) && (y == 0)) {
+
+        if ((x== 0) && (y == 0)) {
             //TODO : which values does it imply?
             throw new UnsupportedOperationException("Not supported yet for 
those coordinates."); //To change body of generated methods, choose Tools | 
Templates.
         }
-               
-        final double ρ = positiveN? hypot(x,y) : -hypot(x,y);
+
+        final double ρ = positiveN ? hypot(x,y) : -hypot(x,y);
         final double θ = atan(x/(-y) ); //undefined if x=y=0
         final double L = (asin(cos_φ1xsin_F1/(ρ*n)) -s0)/n; //undefined if 
x=y=0  //eq.28-26 in Snyder with R=1
-        
+
         //TODO ensure that λ0 will be added. ;  In eq. Snyder 28-23 : λ0 + θ/n
-        dstPts[dstOff  ] =  θ ;//λ 
+        dstPts[dstOff  ] =  θ ;//λ
         dstPts[dstOff+1] = latitudeFromNewtonMethod(L); //φ
     }
-    
+
     protected final double latitudeFromNewtonMethod(final double l){
         double dλ = -PI/2;
         double dλn = Double.MIN_VALUE;
         double A, A2, Δdλ;
-        
+
         int count=0;
         int maxIteration = 100; //TODO : check the value.
-                
-        while((count==0) || dλ-dλn >= (0.1*PI/180)){ //TODO : check the 
condition. It is considered here that convergence is reached when improvement 
is lower than 0.1°.
-            if(count >= maxIteration){
+
+        while ((count==0) || abs(dλ-dλn) >= (0.01*PI/180)){ //TODO : check the 
condition. It is considered here that convergence is reached when improvement 
is lower than 0.01°.
+            if (count >= maxIteration){
                 throw new 
RuntimeException(Resources.format(Resources.Keys.NoConvergence));
             }
             dλn = dλ;
 
-//            λt = l + p2_on_p1 * dλ_n; 
+//            λt = l + p2_on_p1 * dλ_n;
 //            dλ = atan(tan(λt) / cos_i);
 
             A = tan(l + p2_on_p1*dλn) / cos_i;
@@ -376,48 +383,48 @@ public class ConicSatelliteTracking extends 
NormalizedProjection{
         }
 //        λt = L + p2_on_p1 * dλ;
         final double sin_dλ = sin(dλ);
-        return -asin(sin_dλ * sin_i); 
+        return -asin(sin_dλ * sin_i);
     }
-    
-    
+
+
     public double getLatitudeLimit(){
         return latitudeLimit;
     }
-    
+
     /**
      * Method to compute the φn coefficient according to equation 28-9
      * in Snyder's Map Projections manual.
-     * 
+     *
      * @param cos2_φn : square of the φn 's cosinus.
      * @return Fn  coefficient associated with the φn latittude.
      */
     private double computeFn(final double cos2_φn) {
-        return atan((p2_on_p1 * cos2_φn - cos_i) / sqrt(cos2_φn - cos2_i)); // 
eq.28-9 in Snyder 
+        return atan((p2_on_p1 * cos2_φn - cos_i) / sqrt(cos2_φn - cos2_i)); // 
eq.28-9 in Snyder
     }
     /**
      * Method to compute the φn coefficient according to equation 28-2a
      * in Snyder's Map Projections manual.
-     * 
+     *
      * @param sin_φn : φn 's sinus.
      * @return dλn  coefficient associated with the φn latittude.
      */
     private double computedλn(final double sin_φn) {
-        return -asin(sin_φn / sin_i); // eq.28-2a in Snyder 
+        return -asin(sin_φn / sin_i); // eq.28-2a in Snyder
     }
     /**
      * Method to compute the φn coefficient according to equation 28-3a
      * in Snyder's Map Projections manual.
-     * 
+     *
      * @param dλn  coefficient associated with the φn latittude.
      * @return λtn  coefficient associated with the φn latittude.
      */
     private double computeλtn(final double dλn) {
-        return atan(tan(dλn) * cos_i); // eq.28-3a in Snyder 
+        return atan(tan(dλn) * cos_i); // eq.28-3a in Snyder
     }
 //    /**
 //     * Radius of the circle radius of the circle to which groundtracks
 //     * are tangent on the map.
-//     * 
+//     *
 //     * @return radius ρs.
 //     */
 //    public double getRadiusOfTangencyCircle(){
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTracking.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTracking.java
index 1284583..13f8521 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTracking.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTracking.java
@@ -29,15 +29,15 @@ import 
org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.transform.ContextualParameters;
 
 /**
- * <cite>Cylindrical Satellite-Tracking projections</cite>. 
- * 
+ * <cite>Cylindrical Satellite-Tracking projections</cite>.
+ *
  * <cite>
  * - All groundtracks
  * for satellites orbiting the Earth with the same orbital parameters are shown
  * as straight lines on the map.
  *
  * - Cylindrical {@link CylindricalSatelliteTracking}
- * or conical {@link ConicSatelliteTracking} form available. 
+ * or conical {@link ConicSatelliteTracking} form available.
  *
  * - Neither conformal nor equal-area.
  *
@@ -76,13 +76,13 @@ import 
org.apache.sis.referencing.operation.transform.ContextualParameters;
  */
 public class CylindricalSatelliteTracking extends ConicSatelliteTracking {
 
-    
+
     /**
-     * F1' in Snyder : tangente of the angle on both the globe and on the map 
between 
-     * the groundtrack and the meridian at latitude φ1. 
+     * F1' in Snyder : tangente of the angle on both the globe and on the map 
between
+     * the groundtrack and the meridian at latitude φ1.
      */
     final double dF1;
-    
+
     /**
      * Create a Cylindrical Satellite Tracking Projection from the given
      * parameters.
@@ -99,15 +99,15 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
 
     private CylindricalSatelliteTracking(final Initializer initializer) {
         super(initializer);
-        
+
         final double cos2_φ1 = cos_φ1 * cos_φ1;
         dF1 = (p2_on_p1 * cos2_φ1 - cos_i) / sqrt(cos2_φ1 - cos2_i);
-        
+
         final MatrixSIS normalize   = 
context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
 //        final MatrixSIS denormalize = 
context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
 
         normalize  .convertAfter (0, cos_φ1, null);  //For conic tracking
-        
+
 //        denormalize.convertBefore(0, 1/PI,     null);
 //        denormalize.convertBefore(1, , null);
 
@@ -117,10 +117,10 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
      * Converts the specified (λ,φ) coordinate (units in radians) and stores 
the result in {@code dstPts}
      * (linear distance on a unit sphere). In addition, opportunistically 
computes the projection derivative
      * if {@code derivate} is {@code true}.
-     * 
+     *
      * <cite> The Yaxis lies along the central meridian λ0, y increasing 
northerly,
      * and X axis intersects perpendicularly at O_PARALLEL φ0, x increasing 
easterly.
-     * </cite> 
+     * </cite>
      *
      * @return the matrix of the projection derivative at the given source 
position,
      *         or {@code null} if the {@code derivate} argument is {@code 
false}.
@@ -130,12 +130,12 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
     public Matrix transform(double[] srcPts, int srcOff,
             double[] dstPts, int dstOff,
             boolean derivate) throws ProjectionException {
-        
+
         final double λ = srcPts[srcOff];
         final double φ = srcPts[srcOff + 1];
 
         // TODO : check the condition and the thrown exception.
-        if (abs(φ) > PI / 2 - abs(PI / 2 - i)) {  // Exceed tracking limit 
+        if (abs(φ) > PI / 2 - abs(PI / 2 - i)) {  // Exceed tracking limit
             throw new 
ProjectionException(Resources.format(Resources.Keys.CanNotTransformCoordinates_2));
         }
 
@@ -155,8 +155,8 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
         /* 
=====================================================================
         * Uncomputed scale factors :
         *===========================
-        * F' : tangente of the angle on the globe between the groundtrack and 
-        * the meridian at latitude φ 
+        * F' : tangente of the angle on the globe between the groundtrack and
+        * the meridian at latitude φ
         * final double dF = (p2_on_p1 * cos2_φ - cos_i) / sqrt(cos2_φ - 
cos2_i);
         * k = cos_φ1/cos_φ;   // Parallel eq. Snyder 28-7
         * h = k* dF / dF1;    // Meridian eq. Snyder 28-8
@@ -170,7 +170,7 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
 //
 //        final double dy_dλ = 0;
 //        final double dy_dφ =
-                
+
         throw new UnsupportedOperationException("Not supported yet."); //To 
change body of generated methods, choose Tools | Templates.
     }
 
@@ -181,15 +181,15 @@ public class CylindricalSatelliteTracking extends 
ConicSatelliteTracking {
      * @throws ProjectionException if the coordinates can not be converted.
      */
     @Override
-    protected void inverseTransform(double[] srcPts, int srcOff, 
-                                    double[] dstPts, int dstOff) 
+    protected void inverseTransform(double[] srcPts, int srcOff,
+                                    double[] dstPts, int dstOff)
             throws ProjectionException {
-        
+
         final double x   = srcPts[srcOff];
         final double y   = srcPts[srcOff + 1];
-        
+
         final double L   = y * dF1 / cos_φ1; // In eq. Snyder 28-19 : L = y * 
dF1 / R . cos_φ1
-        
+
         dstPts[dstOff  ] =  x;
         dstPts[dstOff+1] = latitudeFromNewtonMethod(L); //φ
     }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTrackingTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTrackingTest.java
index 0b20c88..7152538 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTrackingTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ConicSatelliteTrackingTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sis.referencing.operation.projection;
 
+import static java.lang.Math.sin;
 import java.util.Collections;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.NilReferencingObject;
@@ -26,12 +27,14 @@ import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.datum.DefaultEllipsoid;
 import org.apache.sis.referencing.operation.transform.MathTransformFactoryMock;
 import org.apache.sis.test.DependsOn;
-import static org.junit.Assert.assertTrue;
 import org.junit.Test;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
 
+import static java.lang.StrictMath.toRadians;
+import static org.junit.Assert.assertTrue;
+
 /**
  * Tests coordiantes computed by applying a conic satellite-tracking projection
  * with {@link ConicSatelliteTracking}.
@@ -41,7 +44,6 @@ import org.opengis.util.FactoryException;
  * @since 1.0
  * @module
  */
-@DependsOn(ConformalProjectionTest.class)
 public class ConicSatelliteTrackingTest extends MapProjectionTestCase {
 
     /**
@@ -64,8 +66,8 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
      */
     void createProjection(final double i,
             final double orbitalT, final double ascendingNodeT,
-            final double λ0,       final double φ1, 
-            final double φ2,       final double φ0) 
+            final double λ0, final double φ1,
+            final double φ2, final double φ0)
             throws FactoryException {
 
         final SatelliteTracking provider = new SatelliteTracking();
@@ -73,7 +75,7 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
         final DefaultEllipsoid sphere = DefaultEllipsoid.createEllipsoid(
                 Collections.singletonMap(DefaultEllipsoid.NAME_KEY, 
NilReferencingObject.UNNAMED),
                 1, 1, Units.METRE);
-        
+
         values.parameter("semi_major").setValue(sphere.getSemiMajorAxis());
         values.parameter("semi_minor").setValue(sphere.getSemiMinorAxis());
         values.parameter("satellite_orbit_inclination").setValue(i);
@@ -81,16 +83,16 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
         values.parameter("ascending_node_period").setValue(ascendingNodeT);
         values.parameter("central_meridian").setValue(λ0);
         values.parameter("standard_parallel_1").setValue(φ1);
-        
+
         if (!Double.isNaN(φ2)) {
             values.parameter("standard_parallel_2").setValue(φ2);
-        }else{
+        } else {
             values.parameter("standard_parallel_2").setValue(-φ1); 
//Cylindrical case
         }
         if (!Double.isNaN(φ0)) {
             values.parameter("latitude_of_origin").setValue(φ0);
         }
-        
+
         transform = new 
MathTransformFactoryMock(provider).createParameterizedTransform(values);
         validate();
     }
@@ -98,7 +100,7 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
     /**
      * Tests the projection of a few points on a sphere.
      *
-     * Test based on the numerical example given by Snyder p. 360 to 363 of 
+     * Test based on the numerical example given by Snyder p. 360 to 363 of
      * <cite> Map Projections - A working Manual</cite>
      *
      * @throws FactoryException if an error occurred while creating the map
@@ -109,13 +111,13 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
     public void testTransform() throws FactoryException, TransformException {
         tolerance = 1E-5;
         createProjection(
-                99.092,  //satellite_orbit_inclination
+                99.092, //satellite_orbit_inclination
                 103.267, //satellite_orbital_period
-                1440.0,  //ascending_node_period
-                -90,     //central_meridian
-                45,      //standard_parallel_1
-                70,      //standard_parallel_2
-                30       //latitude_of_origin
+                1440.0, //ascending_node_period
+                -90, //central_meridian
+                45, //standard_parallel_1
+                70, //standard_parallel_2
+                30 //latitude_of_origin
         );
         assertTrue(isInverseTransformSupported);
         verifyTransform(
@@ -126,7 +128,7 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
                     0.2001910, 0.2121685
                 });
     }
-    
+
     /**
      * Tests the projection of a few points on a sphere.
      *
@@ -134,47 +136,111 @@ public class ConicSatelliteTrackingTest extends 
MapProjectionTestCase {
      * Satellite-Tracking Projections shown in table 39 from
      * <cite> Map Projections - A working Manual</cite>
      *
+     * As this table only introduce the values for n, F1 and ρ coefficients, 
the
+     * test was realized by checking these coefficients in debugger mode and by
+     * extracting the computed results of the projection. Thus this method
+     * should be used as a non-regression test.
+     *
      * @throws FactoryException if an error occurred while creating the map
      * projection.
      * @throws TransformException if an error occurred while projecting a 
point.
      */
     @Test
     public void testSampleCoordinates() throws FactoryException, 
TransformException {
-        
+
         //Following tests don't pass with the former tolerance.
-        tolerance = Formulas.LINEAR_TOLERANCE; 
-        
+        tolerance = Formulas.LINEAR_TOLERANCE;
+
         
//----------------------------------------------------------------------
         // φ1 = 30° ; φ2 = 60°
         //---------------------
         createProjection(
-                99.092,  //satellite_orbit_inclination
+                99.092, //satellite_orbit_inclination
                 103.267, //satellite_orbital_period
-                1440.0,  //ascending_node_period
-                -90,     //central_meridian
-                30,      //standard_parallel_1
-                60,      //standard_parallel_2
-                30       //latitude_of_origin
+                1440.0, //ascending_node_period
+                -90, //central_meridian
+                30, //standard_parallel_1
+                60, //standard_parallel_2
+                0 //latitude_of_origin
         );
-//        double xConverterFactor=0.017453;
-//        verifyTransform(
-//                new double[]{ // (λ,φ) coordinates in degrees to project.
-//                      0,  0,
-////                     10,  0, 
-////                    -10, 10,
-////                     60, 40,
-////                     80, 70,
-////                    -120, 80.908  //Tracking limit
-//                },
-//                new double[]{ // Expected (x,y) results in metres.
-//                    0, 0,
-////                    xConverterFactor *   10,  0,
-////                    xConverterFactor *  -10,  0.17579,
-////                    xConverterFactor *   60,  0.79741,
-////                    xConverterFactor *   80,  2.34465,
-////                    xConverterFactor * -120,  7.23571 //Tracking limit
-//                });
-        
-    }
 
+        double n = 0.49073;
+
+        verifyTransform(
+                new double[]{ // (λ,φ) coordinates in degrees to project.
+                       0, -10,
+                       0, 0,
+                       0, 10,
+                       0, 70,
+                    -120, 80.908  //Tracking limit
+                },
+                new double[]{ // Expected (x,y) results in metres.
+                    2.67991 * sin(n * (toRadians(   0 - -90))),    0.46093,
+                    2.38332 * sin(n * (toRadians(   0 - -90))),    0.67369,
+                    2.14662 * sin(n * (toRadians(   0 - -90))),    0.84348,
+                    0.98470 * sin(n * (toRadians(   0 - -90))),    1.67697,
+                    0.50439 * sin(n * (toRadians(-120 - -90))),    1.89549 
//Tracking limit
+                });
+
+        
//----------------------------------------------------------------------
+        // φ1 = 45° ; φ2 = 70°
+        //---------------------
+        createProjection(
+                99.092, //satellite_orbit_inclination
+                103.267, //satellite_orbital_period
+                1440.0, //ascending_node_period
+                -90, //central_meridian
+                45, //standard_parallel_1
+                70, //standard_parallel_2
+                0 //latitude_of_origin
+        );
+
+        n = 0.69478;
+
+        verifyTransform(
+                new double[]{ // (λ,φ) coordinates in degrees to project.
+                    0, -10,
+                    0, 0,
+                    0, 10,
+                    0, 70,
+                    -120, 80.908 //Tracking limit
+                },
+                new double[]{ // Expected (x,y) results in metres.
+                    2.92503 * sin(n * (toRadians(   0 - -90))), 0.90110,
+                    2.25035 * sin(n * (toRadians(   0 - -90))), 1.21232,
+                    1.82978 * sin(n * (toRadians(   0 - -90))), 1.40632,
+                    0.57297 * sin(n * (toRadians(   0 - -90))), 1.98605,
+                    0.28663 * sin(n * (toRadians(-120 - -90))), 1.982485 
//Tracking limit
+                });
+        
//----------------------------------------------------------------------
+        // φ1 = 45° ; φ2 = 70°
+        //---------------------
+        createProjection(
+                99.092, //satellite_orbit_inclination
+                103.267, //satellite_orbital_period
+                1440.0, //ascending_node_period
+                -90, //central_meridian
+                45, //standard_parallel_1
+                80.908, //standard_parallel_2
+                0 //latitude_of_origin
+        );
+
+        n = 0.88475;
+
+        verifyTransform(
+                new double[]{ // (λ,φ) coordinates in degrees to project.
+                       0, -10,
+                       0,  0,
+                       0, 10,
+                       0, 70,
+                    -120, 80.908 //Tracking limit
+                },
+                new double[]{ // Expected (x,y) results in metres.
+                    4.79153 * sin(n * (toRadians(   0 - -90))), 1.80001,
+                    2.66270 * sin(n * (toRadians(   0 - -90))), 2.18329,
+                    1.84527 * sin(n * (toRadians(   0 - -90))), 2.33046,
+                    0.40484 * sin(n * (toRadians(   0 - -90))), 2.58980,
+                    0.21642 * sin(n * (toRadians(-120 - -90))), 2.46908 
//Tracking limit
+                });
+    }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTrackingTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTrackingTest.java
index c207af3..02c1b09 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTrackingTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalSatelliteTrackingTest.java
@@ -35,9 +35,9 @@ import org.opengis.util.FactoryException;
  * @module
  */
 public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest {
-    
-    
-    
+
+
+
     /**
      * Creates a new instance of {@link ConicSatelliteTracking} concatenated
      * with the (de)normalization matrices. The new instance is stored in the
@@ -58,17 +58,17 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
      */
     private void createProjection(final double i,
             final double orbitalT, final double ascendingNodeT,
-            final double λ0,       final double φ1) 
+            final double λ0,       final double φ1)
             throws FactoryException {
         super.createProjection(i, orbitalT, ascendingNodeT, λ0, φ1, NaN, NaN);
     }
-    
+
     /**
      * Tests the projection of a few points on a sphere.
      *
-     * Test based on the numerical example given by Snyder p. 360 to 363 of 
+     * Test based on the numerical example given by Snyder p. 360 to 363 of
      * <cite> Map Projections - A working Manual</cite>
-     * 
+     *
      * @throws FactoryException if an error occurred while creating the map
      * projection.
      * @throws TransformException if an error occurred while projecting a 
point.
@@ -93,7 +93,7 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                     0.2267249, 0.6459071
                 });
     }
-    
+
     /**
      * Tests the projection of a few points on a sphere.
      *
@@ -106,11 +106,12 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
      * @throws TransformException if an error occurred while projecting a 
point.
      */
     @Test
-    public void testSampleCoordinates() throws FactoryException, 
TransformException {
-        
+    public void testSampleCoordinatesCylindricalProjection()
+            throws FactoryException, TransformException {
+
         //Following tests don't pass with the former tolerance.
-        tolerance = Formulas.LINEAR_TOLERANCE; 
-        
+        tolerance = Formulas.LINEAR_TOLERANCE;
+
         
//----------------------------------------------------------------------
         // φ1 = 0°
         //---------
@@ -121,12 +122,12 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                 0,       //central_meridian
                 0        //standard_parallel_1
         );
-       
+
         double xConverterFactor=0.017453;
         verifyTransform(
                 new double[]{ // (λ,φ) coordinates in degrees to project.
                       0,  0,
-                     10,  0, 
+                     10,  0,
                     -10, 10,
                      60, 40,
                      80, 70,
@@ -140,8 +141,8 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                     xConverterFactor *   80,  2.34465,
                     xConverterFactor * -120,  7.23571 //Tracking limit
                 });
-        
-        
+
+
         
//----------------------------------------------------------------------
         // φ1 = +- 30°
         //------------
@@ -152,12 +153,12 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                 0,       //central_meridian
                 -30        //standard_parallel_1
         );
-       
+
         xConverterFactor=0.015115;
         verifyTransform(
                 new double[]{ // (λ,φ) coordinates in degrees to project.
                       0,  0,
-                     10,  0, 
+                     10,  0,
                     -10, 10,
                      60, 40,
                      80, 70,
@@ -171,7 +172,7 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                     xConverterFactor *   80,  1.89918,
                     xConverterFactor * -120,  5.86095 //Tracking limit
                 });
-        
+
         
//----------------------------------------------------------------------
         // φ1 = +- 45°
         //------------
@@ -182,12 +183,12 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                 0,       //central_meridian
                 45        //standard_parallel_1
         );
-       
+
         xConverterFactor=0.012341;
         verifyTransform(
                 new double[]{ // (λ,φ) coordinates in degrees to project.
                       0,  0,
-                     10,  0, 
+                     10,  0,
                     -10, 10,
                      60, 40,
                      80, 70,
@@ -201,8 +202,8 @@ public class CylindricalSatelliteTrackingTest extends 
ConicSatelliteTrackingTest
                     xConverterFactor *   80,  1.37124,
                     xConverterFactor * -120,  4.23171 //Tracking limit
                 });
-        
-        
+
+
     }
-    
+
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
index dec780f..aa68d1f 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
@@ -180,6 +180,8 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.projection.SinusoidalTest.class,
     org.apache.sis.referencing.operation.projection.PolyconicTest.class,
     org.apache.sis.referencing.operation.projection.MollweideTest.class,
+    
org.apache.sis.referencing.operation.projection.ConicSatelliteTrackingTest.class,
+    
org.apache.sis.referencing.operation.projection.CylindricalSatelliteTrackingTest.class,
 
     // Coordinate operation and derived Coordinate Reference Systems (cyclic 
dependency).
     org.apache.sis.referencing.operation.DefaultTransformationTest.class,

Reply via email to