// Longitude and latitude are in degrees. // Output Latitude will be in range [-90, 90]. // Output Longitude will be in range [-180, 180]. // public void UnprojectPoint(double x, double y, out double latitudeDeg, out double longitudeDeg) { if (Double.IsNaN(x)) { throw new ArgumentException(Resource.InputCoordinateIsNaN, "x"); } if (Double.IsNaN(y)) { throw new ArgumentException(Resource.InputCoordinateIsNaN, "y"); } double latitude, longitude; _projection.Unproject(x, y, out latitude, out longitude); if (Double.IsNaN(latitude) || latitude < -Math.PI / 2 || latitude > Math.PI / 2) { throw new ArgumentOutOfRangeException("latitude", String.Format(CultureInfo.InvariantCulture, Resource.OutputLatitudeIsOutOfRange, latitude)); } if (Double.IsNaN(longitude) || longitude < -Math.PI || longitude > Math.PI) { throw new ArgumentOutOfRangeException("longitude", String.Format(CultureInfo.InvariantCulture, Resource.OutputLongitudeIsOutOfRange, longitude)); } latitudeDeg = MathX.Clamp(90, Util.ToDegrees(latitude)); longitudeDeg = MathX.NormalizeLongitudeDeg(Util.ToDegrees(longitude + _projection.CentralLongitudeRad)); }
// longitude0, latitude0, parallel1, parallel2 public AlbersEqualAreaProjection(Dictionary <String, double> parameters) : base(parameters) { double latitude0_rad = InputLatitude("latitude0"); double parallel1_rad = InputLatitude("parallel1"); double parallel2_rad = InputLatitude("parallel2"); double cos_parallel1 = Math.Cos(parallel1_rad); double sin_parallel1 = Math.Sin(parallel1_rad); _n2 = sin_parallel1 + Math.Sin(parallel2_rad); if (Math.Abs(_n2) <= MathX.Tolerance) { throw new ArgumentOutOfRangeException(); } _n = _n2 / 2; _n_half = _n2 / 4; _inv_n2 = 1 / _n2; _inv_n = 2 / _n2; _c = MathX.Square(cos_parallel1) + sin_parallel1 * _n2; _c_over_n2 = _c * _inv_n2; double a = _c - Math.Sin(latitude0_rad) * _n2; if (a < 0) { throw new ArgumentOutOfRangeException(); } _ro_0 = Math.Sqrt(a) * _inv_n; }
protected internal override void Unproject(double x, double y, out double latitude, out double longitude) { double ro = Math.Sign(_n) * Math.Sqrt(x * x + MathX.Square(_ro_0 - y)); // If ro is zero or very small then 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, _ro_0 - y) * _nInv); }
protected internal override void Unproject(double x, double y, out double latitude, out double longitude) { double ros = x * x + (_ro_0 - y) * (_ro_0 - y); double a = _c_over_n2 - ros * _n_half; if (Double.IsNaN(a) || Math.Abs(a) > 1 + MathX.Tolerance) { throw new ArgumentOutOfRangeException("x, y"); } latitude = Math.Asin(MathX.Clamp(1, a)); longitude = MathX.Clamp(Math.PI, MathX.Atan2(x, _ro_0 - y, "x, y") * _inv_n); }
// Longitude and latitude are in degrees. // Input Latitude must be in range [-90, 90]. // Input Longitude must be in range [-15069, 15069]. // public void ProjectPoint(double latitudeDeg, double longitudeDeg, out double x, out double y) { double latitude = MathX.InputLat(latitudeDeg, 90, "latitude"); double longitude = MathX.NormalizeLongitudeRad(MathX.InputLong(longitudeDeg, 15069, "longitude") - _projection.CentralLongitudeRad); _projection.Project(latitude, longitude, out x, out y); if (Double.IsNaN(x)) { throw new ArgumentOutOfRangeException("x"); } if (Double.IsNaN(y)) { throw new ArgumentOutOfRangeException("y"); } }
protected internal override void Project(double latitude, double longitude, out double x, out double y) { double sin_lat = Math.Sin(latitude); double cos_lat = Math.Cos(latitude); double sin_long = Math.Sin(longitude); double cos_long = Math.Cos(longitude); double a = _sin_fi_p * sin_lat - _cos_fi_p * cos_lat * sin_long; // sin_fi_p if (Double.IsNaN(a) || Math.Abs(a) > 1) { throw new ArgumentOutOfRangeException("latitude, longitude"); } x = MathX.Atan2(sin_lat / cos_lat * _cos_fi_p + sin_long * _sin_fi_p, cos_long, "latitude, longitude"); y = MathX.Clamp(MaxY, Math.Log((1 + a) / (1 - a)) / 2); // protect againt +-Infinity }
protected internal override void Unproject(double x, double y, out double latitude, out double longitude) { double sin_x = Math.Sin(x); double cos_x = Math.Cos(x); double sinh_y = Math.Sinh(y); double cosh_y = Math.Cosh(y); // cosh_y >= 1 by definition double a = (_sin_fi_p * sinh_y + _cos_fi_p * sin_x) / cosh_y; if (Math.Abs(a) > 1) { throw new ArgumentOutOfRangeException("x, y"); } latitude = Math.Asin(a); longitude = MathX.Atan2(_sin_fi_p * sin_x - _cos_fi_p * sinh_y, cos_x, "x, y"); }
protected internal override void Unproject(double x, double y, out double latitude, out double longitude) { if (x >= MaxX) { latitude = 0; longitude = Math.PI / 2; } else if (x <= -MaxX) { latitude = 0; longitude = -Math.PI / 2; } else { // 1 <= cosh(x) <= cosh(MaxX) latitude = Math.Asin(Math.Sin(y) / Math.Cosh(x)); // In case of x=0 and y=+-Pi/2: latitude will be +-90 and longtude will be 0 longitude = MathX.Atan2(Math.Sinh(x), Math.Cos(y)); } }
// x will be in range [-MaxX, MaxX] // y will be in range [-Pi, Pi] protected internal override void Project(double latitude, double longitude, out double x, out double y) { // North pole if (latitude >= Math.PI / 2 - MathX.Tolerance) { x = 0; y = Math.PI / 2; return; } // South pole if (latitude <= -Math.PI / 2 + MathX.Tolerance) { x = 0; y = -Math.PI / 2; return; } if (Math.Abs(latitude) <= MathX.Tolerance) { // East of India if (Math.Abs(longitude - Math.PI / 2) <= MathX.Tolerance) { x = MaxX; y = 0; return; } // West of South America if (Math.Abs(longitude + Math.PI / 2) <= MathX.Tolerance) { x = -MaxX; y = 0; return; } } double b = Math.Cos(latitude) * Math.Sin(longitude); x = MathX.Clamp(MaxX, Math.Log((1 + b) / (1 - b)) / 2); y = Math.Atan2(Math.Tan(latitude), Math.Cos(longitude)); }
protected internal double InputLongitude(string name, double max) { return(MathX.InputLong(_parameters[name], max, name)); }
protected internal override void Project(double latitude, double longitude, out double x, out double y) { x = longitude; y = MathX.Clamp(MaxY, Math.Log(Math.Tan(Math.PI / 4 + latitude / 2))); // protect againt +-Infinity }