// longitude0, latitude0, parallel1, parallel2 public AlbersEqualAreaProjection(IDictionary <string, double> parameters) : base(parameters) { var latitude0Rad = InputLatitude("latitude0"); var parallel1Rad = InputLatitude("parallel1"); var parallel2Rad = InputLatitude("parallel2"); var cosParallel1 = Math.Cos(parallel1Rad); var sinParallel1 = Math.Sin(parallel1Rad); _n2 = sinParallel1 + Math.Sin(parallel2Rad); if (Math.Abs(_n2) <= MathX.Tolerance) { throw new ArgumentOutOfRangeException(); } _n = _n2 / 2; _nHalf = _n2 / 4; var invN2 = 1 / _n2; _invN = 2 / _n2; _c = MathX.Square(cosParallel1) + sinParallel1 * _n2; _cOverN2 = _c * invN2; var a = _c - Math.Sin(latitude0Rad) * _n2; if (a < 0) { throw new ArgumentOutOfRangeException(); } _ro0 = Math.Sqrt(a) * _invN; }
protected internal override void Unproject(double x, double y, out double latitude, out double longitude) { var ro = Math.Sign(_n) * Math.Sqrt(x * x + MathX.Square(_ro0 - y)); // If ro is zero or very small then latitude will be +-Pi/2 depending on the sign of f. latitude = 2 * Math.Atan(Math.Pow(_f / ro, _nInv)) - Math.PI / 2; longitude = MathX.Clamp(Math.PI, Math.Atan2(x, _ro0 - y) * _nInv); }