///<summary> /// Inverse-projects a point (in the units defined by the coordinate system), /// producing a geographic result (in radians) ///</summary> /// <param name="src">the input projected coordinate (in coordinate system units)</param> /// <param name="dst">the inverse-projected geographic coordinate (in radians)</param> /// <returns>the target coordinate</returns> public Coordinate InverseProjectRadians(Coordinate src, Coordinate dst) { double x; double y; if (_unit == Units.Units.Degrees) { // convert DD to radians x = src.X * DTR; y = src.Y * DTR; } else { x = (src.X - _totalFalseEasting) / _totalScale; y = (src.Y - _totalFalseNorthing) / _totalScale; } ProjectInverse(x, y, dst); if (dst.X < -Math.PI) { dst.X = -Math.PI; } else if (dst.X > Math.PI) { dst.X = Math.PI; } if (_projectionLongitude != 0) { dst.X = ProjectionMath.NormalizeLongitude(dst.X + _projectionLongitude); } return(dst); }
///<summary> /// Projects a geographic point (in radians), producing a projected result /// (in the units of the target coordinate system). ///</summary> /// <param name="src">the input geographic coordinate (in radians)</param> /// <param name="dst">the projected coordinate (in coordinate system units)</param> /// <returns>the target coordinate</returns> public Coordinate ProjectRadians(Coordinate src, Coordinate dst) { double x = src.X; if (_projectionLongitude != 0) { x = ProjectionMath.NormalizeLongitude(x - _projectionLongitude); } return(ProjectRadians(x, src.Y, dst)); }
public int GetZoneFromNearestMeridian(double longitude) { int zone = (int)Math.Floor((ProjectionMath.NormalizeLongitude(longitude) + Math.PI) * 30.0 / Math.PI) + 1; if (zone < 1) { zone = 1; } else if (zone > 60) { zone = 60; } return(zone); }
public override Coordinate Project(Coordinate input, Coordinate output) { double lon = ProjectionMath.NormalizeLongitude(input.X - ProjectionLongitude); double lat = input.Y; double hold2 = Math.Pow(((1.0 - _eccentricity * Math.Sin(lat)) / (1.0 + _eccentricity * Math.Sin(lat))), 0.5 * _eccentricity); double hold3 = Math.Tan(ProjectionMath.PiFourth - 0.5 * lat); double hold1 = (hold3 == 0.0) ? 0.0 : Math.Pow(hold3 / hold2, _n); double rho = _radius * _f * hold1; double theta = _n * lon; output.X = rho * Math.Sin(theta); output.Y = _rho0 - rho * Math.Cos(theta); return(output); }
public override void Initialize() { base.Initialize(); double con, com, cosphi0, d, f, h, l, sinphi0, p, j; //FIXME-setup rot, alpha, longc,lon/lat1/2 rot = true; lamc = _lonc; // true if alpha provided int azi = Double.IsNaN(Alpha) ? 0 : 1; if (azi != 0) { // alpha specified if (Math.Abs(Alpha) <= Tolerance || Math.Abs(Math.Abs(ProjectionLatitude) - ProjectionMath.PiHalf) <= Tolerance || Math.Abs(Math.Abs(Alpha) - ProjectionMath.PiHalf) <= Tolerance) { throw new ProjectionException("Obl 1"); } } else { if (Math.Abs(phi1 - phi2) <= Tolerance || (con = Math.Abs(phi1)) <= Tolerance || Math.Abs(con - ProjectionMath.PiHalf) <= Tolerance || Math.Abs(Math.Abs(ProjectionLatitude) - ProjectionMath.PiHalf) <= Tolerance || Math.Abs(Math.Abs(phi2) - ProjectionMath.PiHalf) <= Tolerance) { throw new ProjectionException("Obl 2"); } } com = (_spherical = (EccentricitySquared == 0.0)) ? 1 : Math.Sqrt(_oneEs); if (Math.Abs(ProjectionLatitude) > EPS10) { sinphi0 = Math.Sin(ProjectionLatitude); cosphi0 = Math.Cos(ProjectionLatitude); if (!Spherical) { con = 1.0 - EccentricitySquared * sinphi0 * sinphi0; bl = cosphi0 * cosphi0; bl = Math.Sqrt(1.0 + EccentricitySquared * bl * bl / _oneEs); al = bl * ScaleFactor * com / con; d = bl * com / (cosphi0 * Math.Sqrt(con)); } else { bl = 1.0; al = ScaleFactor; d = 1.0 / cosphi0; } if ((f = d * d - 1.0) <= 0.0) { f = 0.0; } else { f = Math.Sqrt(f); if (ProjectionLatitude < 0.0) { f = -f; } } el = f += d; if (!Spherical) { el *= Math.Pow(ProjectionMath.tsfn(ProjectionLatitude, sinphi0, Eccentricity), bl); } else { el *= Math.Tan(.5 * (ProjectionMath.PiHalf - ProjectionLatitude)); } } else { bl = 1.0 / com; al = ScaleFactor; el = d = f = 1.0; } if (azi != 0) { Gamma = Math.Asin(Math.Sin(Alpha) / d); ProjectionLongitude = lamc - Math.Asin((.5 * (f - 1.0 / f)) * Math.Tan(Gamma)) / bl; } else { if (!Spherical) { h = Math.Pow(ProjectionMath.tsfn(phi1, Math.Sin(phi1), Eccentricity), bl); l = Math.Pow(ProjectionMath.tsfn(phi2, Math.Sin(phi2), Eccentricity), bl); } else { h = Math.Tan(.5 * (ProjectionMath.PiHalf - phi1)); l = Math.Tan(.5 * (ProjectionMath.PiHalf - phi2)); } f = el / h; p = (l - h) / (l + h); j = el * el; j = (j - l * h) / (j + l * h); if ((con = lam1 - lam2) < -Math.PI) { lam2 -= ProjectionMath.TwoPI; } else if (con > Math.PI) { lam2 += ProjectionMath.TwoPI; } ProjectionLongitude = ProjectionMath.NormalizeLongitude(.5 * (lam1 + lam2) - Math.Atan( j * Math.Tan(.5 * bl * (lam1 - lam2)) / p) / bl); Gamma = Math.Atan(2.0 * Math.Sin(bl * ProjectionMath.NormalizeLongitude(lam1 - ProjectionLongitude)) / (f - 1.0 / f)); Alpha = Math.Asin(d * Math.Sin(Gamma)); } singam = Math.Sin(Gamma); cosgam = Math.Cos(Gamma); // f = MapMath.param(params, "brot_conv").i ? Gamma : alpha; f = Alpha;//FIXME sinrot = Math.Sin(f); cosrot = Math.Cos(f); // u_0 = MapMath.param(params, "bno_uoff").i ? 0. : u_0 = false ? 0.0 ://FIXME Math.Abs(al * Math.Atan(Math.Sqrt(d * d - 1.0) / cosrot) / bl); if (ProjectionLatitude < 0.0) { u_0 = -u_0; } }
private PhiLambda Convert(PhiLambda input, bool inverse) { var tb = input; tb.Lambda -= LowerLeft.Lambda; tb.Phi -= LowerLeft.Phi; tb.Lambda = ProjectionMath.NormalizeLongitude(tb.Lambda - Math.PI) + Math.PI; var t = InterpolateGrid(tb); if (inverse) { PhiLambda dif; int i = MaxIterations; if (t.Lambda == HugeValue) { return(t); } t.Lambda = tb.Lambda + t.Lambda; t.Phi = tb.Phi - t.Phi; do { var del = InterpolateGrid(t); /* This case used to return failure, but I have * changed it to return the first order approximation * of the inverse shift. This avoids cases where the * grid shift *into* this grid came from another grid. * While we aren't returning optimally correct results * I feel a close result in this case is better than * no result. NFW * To demonstrate use -112.5839956 49.4914451 against * the NTv2 grid shift file from Canada. */ if (del.Lambda == HugeValue) { Debug.WriteLine("InverseShiftFailed"); break; } t.Lambda -= dif.Lambda = t.Lambda - del.Lambda - tb.Lambda; t.Phi -= dif.Phi = t.Phi + del.Phi - tb.Phi; } while (i-- > 0 && Math.Abs(dif.Lambda) > Tolerance && Math.Abs(dif.Phi) > Tolerance); if (i < 0) { Debug.WriteLine("InvShiftConvergeFailed"); t.Lambda = t.Phi = HugeValue; return(t); } input.Lambda = ProjectionMath.NormalizeLongitude(t.Lambda + LowerLeft.Lambda); input.Phi = t.Phi + LowerLeft.Phi; } else { if (t.Lambda == HugeValue) { input = t; } else { input.Lambda -= t.Lambda; input.Phi += t.Phi; } } return(input); }
public double GetWidth(double y) { return(ProjectionMath.NormalizeLongitude(Math.PI) * Math.Cos(y)); }