示例#1
0
        static int numit0_ = 20; // Newton iterations in Init

        /**
         * ructor with a single standard parallel.
         *
         * @param[in] a equatorial radius of ellipsoid (meters).
         * @param[in] f flattening of ellipsoid.  Setting \e f = 0 gives a sphere.
         *   Negative \e f gives a prolate ellipsoid.
         * @param[in] stdlat standard parallel (degrees), the circle of tangency.
         * @param[in] k0 azimuthal scale on the standard parallel.
         * @exception new GeographicException if \e a, (1 − \e f) \e a, or \e k0 is
         *   not positive.
         * @exception new GeographicException if \e stdlat is not in [−90°,
         *   90°].
         **********************************************************************/
        public AlbersEqualArea(double a, double f, double stdlat, double k0)
        {
            InitVars(a, f);

            if (!(GeoMath.IsFinite(_a) && _a > 0))
            {
                throw new GeographicException("Equatorial radius is not positive");
            }
            if (!(GeoMath.IsFinite(_f) && _f < 1))
            {
                throw new GeographicException("Polar semi-axis is not positive");
            }
            if (!(GeoMath.IsFinite(k0) && k0 > 0))
            {
                throw new GeographicException("Scale is not positive");
            }
            if (!(Math.Abs(stdlat) <= 90))
            {
                throw new GeographicException("Standard latitude not in [-90d, 90d]");
            }
            double sphi, cphi;

            GeoMath.Sincosd(stdlat, out sphi, out cphi);
            Init(sphi, cphi, sphi, cphi, k0);
        }
示例#2
0
        /**
         * Set the azimuthal scale for the projection.
         *
         * @param[in] lat (degrees).
         * @param[in] k azimuthal scale at latitude \e lat (default 1).
         * @exception new GeographicException \e k is not positive.
         * @exception new GeographicException if \e lat is not in (&minus;90&deg;,
         *   90&deg;).
         *
         * This allows a "latitude of conformality" to be specified.
         **********************************************************************/
        public void SetScale(double lat, double k = 1)
        {
            if (!(GeoMath.IsFinite(k) && k > 0))
            {
                throw new GeographicException("Scale is not positive");
            }
            if (!(Math.Abs(lat) < 90))
            {
                throw new GeographicException("Latitude for SetScale not in (-90d, 90d)");
            }
            double x, y, gamma, kold;

            Forward(0, lat, 0, out x, out y, out gamma, out kold);
            k   /= kold;
            _k0 *= k;
            _k2  = GeoMath.Square(_k0);
        }
示例#3
0
        /**
         * ructor with two standard parallels.
         *
         * @param[in] a equatorial radius of ellipsoid (meters).
         * @param[in] f flattening of ellipsoid.  Setting \e f = 0 gives a sphere.
         *   Negative \e f gives a prolate ellipsoid.
         * @param[in] stdlat1 first standard parallel (degrees).
         * @param[in] stdlat2 second standard parallel (degrees).
         * @param[in] k1 azimuthal scale on the standard parallels.
         * @exception new GeographicException if \e a, (1 &minus; \e f) \e a, or \e k1 is
         *   not positive.
         * @exception new GeographicException if \e stdlat1 or \e stdlat2 is not in
         *   [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
         *   opposite poles.
         **********************************************************************/
        public AlbersEqualArea(double a, double f, double stdlat1, double stdlat2, double k1)
        {
            InitVars(a, f);

            eps_   = GeoMath.Epsilon;
            epsx_  = GeoMath.Square(eps_);
            epsx2_ = GeoMath.Square(epsx_);
            tol_   = GeoMath.Square(eps_);
            tol0_  = (tol_ * GeoMath.Square(GeoMath.Square(eps_)));
            _a     = a;
            _f     = f;
            _fm    = 1 - _f;
            _e2    = _f * (2 - _f);
            _e     = GeoMath.Square(Math.Abs(_e2));
            _e2m   = 1 - _e2;
            _qZ    = 1 + _e2m * atanhee(1);
            _qx    = _qZ / (2 * _e2m);

            if (!(GeoMath.IsFinite(_a) && _a > 0))
            {
                throw new GeographicException("Equatorial radius is not positive");
            }
            if (!(GeoMath.IsFinite(_f) && _f < 1))
            {
                throw new GeographicException("Polar semi-axis is not positive");
            }
            if (!(GeoMath.IsFinite(k1) && k1 > 0))
            {
                throw new GeographicException("Scale is not positive");
            }
            if (!(Math.Abs(stdlat1) <= 90))
            {
                throw new GeographicException("Standard latitude 1 not in [-90d, 90d]");
            }
            if (!(Math.Abs(stdlat2) <= 90))
            {
                throw new GeographicException("Standard latitude 2 not in [-90d, 90d]");
            }
            double sphi1, cphi1, sphi2, cphi2;

            GeoMath.Sincosd(stdlat1, out sphi1, out cphi1);
            GeoMath.Sincosd(stdlat2, out sphi2, out cphi2);
            Init(sphi1, cphi1, sphi2, cphi2, k1);
        }
示例#4
0
        /**
         * Constructor for a ellipsoid with
         *
         * @param[in] a equatorial radius (meters).
         * @param[in] f flattening of ellipsoid.  Setting \e f = 0 gives a sphere.
         *   Negative \e f gives a prolate ellipsoid.
         * @exception GeographicErr if \e a or (1 &minus; \e f) \e a is not
         *   positive.
         **********************************************************************/
        public Geocentric(double a, double f)
        {
            _a      = a;
            _f      = f;
            _e2     = _f * (2 - _f);
            _e2m    = GeoMath.Square(1 - _f);
            _e2a    = Math.Abs(_e2);
            _e4a    = GeoMath.Square(_e2);
            _maxrad = 2 * _a / GeoMath.Epsilon;

            if (!(GeoMath.IsFinite(_a) && _a > 0))
            {
                throw new GeographicException("Equatorial radius is not positive");
            }
            if (!(GeoMath.IsFinite(_f) && _f < 1))
            {
                throw new GeographicException("Polar semi-axis is not positive");
            }
        }
示例#5
0
        /**
         * ructor with two standard parallels specified by sines and cosines.
         *
         * @param[in] a equatorial radius of ellipsoid (meters).
         * @param[in] f flattening of ellipsoid.  Setting \e f = 0 gives a sphere.
         *   Negative \e f gives a prolate ellipsoid.
         * @param[in] sinlat1 sine of first standard parallel.
         * @param[in] coslat1 cosine of first standard parallel.
         * @param[in] sinlat2 sine of second standard parallel.
         * @param[in] coslat2 cosine of second standard parallel.
         * @param[in] k1 azimuthal scale on the standard parallels.
         * @exception new GeographicException if \e a, (1 &minus; \e f) \e a, or \e k1 is
         *   not positive.
         * @exception new GeographicException if \e stdlat1 or \e stdlat2 is not in
         *   [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
         *   opposite poles.
         *
         * This allows parallels close to the poles to be specified accurately.
         * This routine computes the latitude of origin and the azimuthal scale at
         * this latitude.  If \e dlat = abs(\e lat2 &minus; \e lat1) &le; 160&deg;,
         * then the error in the latitude of origin is less than 4.5 &times;
         * 10<sup>&minus;14</sup>d;.
         **********************************************************************/
        public AlbersEqualArea(double a, double f,
                               double sinlat1, double coslat1,
                               double sinlat2, double coslat2,
                               double k1)
        {
            InitVars(a, f);

            if (!(GeoMath.IsFinite(_a) && _a > 0))
            {
                throw new GeographicException("Equatorial radius is not positive");
            }
            if (!(GeoMath.IsFinite(_f) && _f < 1))
            {
                throw new GeographicException("Polar semi-axis is not positive");
            }
            if (!(GeoMath.IsFinite(k1) && k1 > 0))
            {
                throw new GeographicException("Scale is not positive");
            }
            if (!(coslat1 >= 0))
            {
                throw new GeographicException("Standard latitude 1 not in [-90d, 90d]");
            }
            if (!(coslat2 >= 0))
            {
                throw new GeographicException("Standard latitude 2 not in [-90d, 90d]");
            }
            if (!(Math.Abs(sinlat1) <= 1 && coslat1 <= 1) || (coslat1 == 0 && sinlat1 == 0))
            {
                throw new GeographicException("Bad sine/cosine of standard latitude 1");
            }
            if (!(Math.Abs(sinlat2) <= 1 && coslat2 <= 1) || (coslat2 == 0 && sinlat2 == 0))
            {
                throw new GeographicException("Bad sine/cosine of standard latitude 2");
            }
            if (coslat1 == 0 && coslat2 == 0 && sinlat1 * sinlat2 <= 0)
            {
                throw new GeographicException
                          ("Standard latitudes cannot be opposite poles");
            }
            Init(sinlat1, coslat1, sinlat2, coslat2, k1);
        }
        /**
         * Constructor for a ellipsoid with
         *
         * @param[in] a equatorial radius (meters).
         * @param[in] f flattening of ellipsoid.  Setting \e f = 0 gives a sphere.
         *   Negative \e f gives a prolate ellipsoid.
         * @param[in] k0 central scale factor.
         * @exception GeographicErr if \e a, (1 &minus; \e f) \e a, or \e k0 is
         *   not positive.
         **********************************************************************/
        public TransverseMercator(double a, double f, double k0)
        {
            _a   = a;
            _f   = f;
            _k0  = k0;
            _e2  = _f * (2 - _f);
            _es  = (f < 0 ? -1 : 1) * Math.Sqrt(Math.Abs(_e2));
            _e2m = 1 - _e2;
            // _c = Math.Sqrt( pow(1 + _e, 1 + _e) * pow(1 - _e, 1 - _e) ) )
            // See, for example, Lee (1976), p 100.
            _c = Math.Sqrt(_e2m) * Math.Exp(GeoMath.Eatanhe(1, _es));
            _n = _f / (2 - _f);


            if (!(GeoMath.IsFinite(_a) && _a > 0))
            {
                throw new GeographicException("Equatorial radius is not positive");
            }
            if (!(GeoMath.IsFinite(_f) && _f < 1))
            {
                throw new GeographicException("Polar semi-axis is not positive");
            }
            if (!(GeoMath.IsFinite(_k0) && _k0 > 0))
            {
                throw new GeographicException("Scale is not positive");
            }

            double[] b1coeff =
            {
                // b1*(n+1), polynomial in n2 of order 3
                1, 4, 64, 256, 256,
            };

            double[] alpcoeff =
            {
                // alp[1]/n^1, polynomial in n of order 5
                31564,        -66675,   34440,    47250, -100800,   75600, 151200,
                // alp[2]/n^2, polynomial in n of order 4
                -1983433,     863232,  748608, -1161216,  524160, 1935360,
                // alp[3]/n^3, polynomial in n of order 3
                670412,       406647, -533952,   184464,  725760,
                // alp[4]/n^4, polynomial in n of order 2
                6601661,    -7732800, 2230245,  7257600,
                // alp[5]/n^5, polynomial in n of order 1
                -13675556,   3438171, 7983360,
                // alp[6]/n^6, polynomial in n of order 0
                212378941, 319334400,
            };  // count = 27

            double[] betcoeff =
            {
                // bet[1]/n^1, polynomial in n of order 5
                384796,     -382725,    -6720,  932400, -1612800, 1209600, 2419200,
                // bet[2]/n^2, polynomial in n of order 4
                -1118711,   1695744, -1174656,  258048,    80640, 3870720,
                // bet[3]/n^3, polynomial in n of order 3
                22276,       -16929,   -15984,   12852,   362880,
                // bet[4]/n^4, polynomial in n of order 2
                -830251,    -158400,   197865, 7257600,
                // bet[5]/n^5, polynomial in n of order 1
                -435388,     453717, 15966720,
                // bet[6]/n^6, polynomial in n of order 0
                20648693, 638668800,
            };  // count = 27

            int m = maxpow_ / 2;

            _b1 = GeoMath.PolyVal(m, b1coeff, 0, GeoMath.Square(_n)) / (b1coeff[m + 1] * (1 + _n));
            // _a1 is the equivalent radius for computing the circumference of
            // ellipse.
            _a1 = _b1 * _a;
            int    o = 0;
            double d = _n;

            for (int l = 1; l <= maxpow_; ++l)
            {
                m       = maxpow_ - l;
                _alp[l] = d * GeoMath.PolyVal(m, alpcoeff, o, _n) / alpcoeff[o + m + 1];
                _bet[l] = d * GeoMath.PolyVal(m, betcoeff, o, _n) / betcoeff[o + m + 1];
                o      += m + 2;
                d      *= _n;
            }
            // Post condition: o == sizeof(alpcoeff) / sizeof(double) &&
            // o == sizeof(betcoeff) / sizeof(double)
        }