예제 #1
0
        /// <summary>
        /// Initializes the transform using the parameters from the specified coordinate system information
        /// </summary>
        /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param>
        protected override void OnInit(ProjectionInfo projInfo)
        {
            if (Es != 0)
            {
                _en = MeridionalDistance.GetEn(Es);
                if (_en == null)
                {
                    throw new ProjectionException(0);
                }

                _ml0 = MeridionalDistance.MeridionalLength(Phi0, Math.Sin(Phi0), Math.Cos(Phi0), _en);
                _esp = Es / (1 - Es);
            }
            else
            {
                _esp = K0;
                _ml0 = .5 * _esp;
            }
        }
예제 #2
0
        /// <summary>
        /// The forward transform where the spheroidal model of the earth has a flattening factor,
        /// matching more closely with the oblique spheroid of the actual earth
        /// </summary>
        /// <param name="lp">The double values for geodetic lambda and phi organized into a one dimensional array</param>
        /// <param name="xy">The double values for linear x and y organized into a one dimensional array</param>
        /// <param name="startIndex">The zero based integer start index</param>
        /// <param name="numPoints">The integer count of the number of xy pairs in the lp and xy arrays</param>
        protected override void EllipticalForward(double[] lp, double[] xy, int startIndex, int numPoints)
        {
            for (int i = startIndex; i < startIndex + numPoints; i++)
            {
                int phi = i * 2 + PHI;
                int lam = i * 2 + LAMBDA;
                int x   = i * 2 + X;
                int y   = i * 2 + Y;

                /*
                 * Fail if our longitude is more than 90 degrees from the
                 * central meridian since the results are essentially garbage.
                 * Is error -20 really an appropriate return value?
                 *
                 *  http://trac.osgeo.org/proj/ticket/5
                 */
                if (lp[lam] < -HALF_PI || lp[lam] > HALF_PI)
                {
                    xy[x] = double.NaN;
                    xy[y] = double.NaN;
                    continue;
                    //ProjectionException(14);
                }
                double sinphi = Math.Sin(lp[phi]);
                double cosphi = Math.Cos(lp[phi]);
                double t      = Math.Abs(cosphi) > 1E-10 ? sinphi / cosphi : 0;
                t *= t;
                double al  = cosphi * lp[lam];
                double als = al * al;
                al /= Math.Sqrt(1 - Es * sinphi * sinphi);
                double n = _esp * cosphi * cosphi;
                xy[x] = K0 * al * (FC1 +
                                   FC3 * als * (1 - t + n +
                                                FC5 * als * (5 + t * (t - 18) + n * (14 - 58 * t) +
                                                             FC7 * als * (61 + t * (t * (179 - t) - 479)))));
                xy[y] = K0 * (MeridionalDistance.MeridionalLength(lp[phi], sinphi, cosphi, _en) - _ml0 +
                              sinphi * al * lp[lam] * FC2 * (1 +
                                                             FC4 * als * (5 - t + n * (9 + 4 * n) +
                                                                          FC6 * als * (61 + t * (t - 58) + n * (270 - 330 * t) +
                                                                                       FC8 * als * (1385 + t * (t * (543 - t) - 3111))))));
            }
        }
예제 #3
0
 /// <summary>
 /// Performs the inverse transfrom from a single coordinate of linear units to the same coordinate in geodetic units
 /// </summary>
 /// <param name="xy">The double linear input x and y values organized into a 1 dimensional array</param>
 /// <param name="lp">The double geodetic output lambda and phi values organized into a 1 dimensional array</param>
 /// <param name="startIndex">The zero based integer start index</param>
 /// <param name="numPoints">The integer count of the number of xy pairs in the lp and xy arrays</param>
 protected override void EllipticalInverse(double[] xy, double[] lp, int startIndex, int numPoints)
 {
     for (int i = startIndex; i < startIndex + numPoints; i++)
     {
         int phi = i * 2 + PHI;
         int lam = i * 2 + LAMBDA;
         int x   = i * 2 + X;
         int y   = i * 2 + Y;
         lp[phi] = MeridionalDistance.AngularDistance(_ml0 + xy[y] / K0, Es, _en);
         if (Math.Abs(lp[phi]) >= HALF_PI)
         {
             lp[phi] = xy[y] < 0 ? -HALF_PI : HALF_PI;
             lp[lam] = 0;
         }
         else
         {
             double sinphi = Math.Sin(lp[phi]);
             double cosphi = Math.Cos(lp[phi]);
             double t      = Math.Abs(cosphi) > 1e-10 ? sinphi / cosphi : 0;
             double n      = _esp * cosphi * cosphi;
             double con;
             double d = xy[x] * Math.Sqrt(con = 1 - Es * sinphi * sinphi) / K0;
             con *= t;
             t   *= t;
             double ds = d * d;
             lp[phi] -= (con * ds / (1 - Es)) * FC2 * (1 -
                                                       ds * FC4 * (5 + t * (3 - 9 * n) + n * (1 - 4 * n) -
                                                                   ds * FC6 * (61 + t * (90 - 252 * n +
                                                                                         45 * t) + 46 * n
                                                                               - ds * FC8 * (1385 + t * (3633 + t * (4095 + 1574 * t))))));
             lp[lam] = d * (FC1 -
                            ds * FC3 * (1 + 2 * t + n -
                                        ds * FC5 * (5 + t * (28 + 24 * t + 8 * n) + 6 * n
                                                    - ds * FC7 * (61 + t * (662 + t * (1320 + 720 * t)))))) / cosphi;
         }
     }
 }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="arg"></param>
 /// <param name="es"></param>
 /// <param name="en"></param>
 /// <returns></returns>
 public static double InvMlfn(double arg, double es, double[] en)
 {
     return(MeridionalDistance.AngularDistance(arg, es, en));
 }
예제 #5
0
 /// <summary>
 /// Meridonal length function
 /// </summary>
 /// <param name="phi"></param>
 /// <param name="sphi"></param>
 /// <param name="cphi"></param>
 /// <param name="en"></param>
 /// <returns></returns>
 public static double Mlfn(double phi, double sphi, double cphi, double[] en)
 {
     return(MeridionalDistance.MeridionalLength(phi, sphi, cphi, en));
 }
예제 #6
0
 /// <summary>
 /// Obtains the EN parameters for the Meridional distance
 /// </summary>
 /// <param name="es"></param>
 /// <returns></returns>
 public static double[] Enfn(double es)
 {
     return(MeridionalDistance.GetEn(es));
 }