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); }
/** * 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 (−90°, * 90°). * * 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); }
/** * 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 − \e f) \e a, or \e k1 is * not positive. * @exception new GeographicException if \e stdlat1 or \e stdlat2 is not in * [−90°, 90°], 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); }
/** * 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 − \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"); } }
/** * 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 − \e f) \e a, or \e k1 is * not positive. * @exception new GeographicException if \e stdlat1 or \e stdlat2 is not in * [−90°, 90°], 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 − \e lat1) ≤ 160°, * then the error in the latitude of origin is less than 4.5 × * 10<sup>−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 − \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) }