/** * Set the central point of the projection * * @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees). * * \e lat0 should be in the range [−90°, 90°]. **********************************************************************/ public void Reset(double lat0, double lon0) { _meridian = _earth.Line(lat0, lon0, 0, GeodesicMask.LATITUDE | GeodesicMask.LONGITUDE | GeodesicMask.DISTANCE | GeodesicMask.DISTANCE_IN | GeodesicMask.AZIMUTH); double f = _earth.Flattening(); GeoMath.Sincosd(LatitudeOrigin(), out _sbet0, out _cbet0); _sbet0 *= (1 - f); GeoMath.Norm(ref _sbet0, ref _cbet0); }
/** * Forward projection, from geographic to Cassini-Soldner. * * @param[in] lat latitude of point (degrees). * @param[in] lon longitude of point (degrees). * @param[out] x easting of point (meters). * @param[out] y northing of point (meters). * @param[out] azi azimuth of easting direction at point (degrees). * @param[out] rk reciprocal of azimuthal northing scale at point. * * \e lat should be in the range [−90°, 90°]. A call to * Forward followed by a call to Reverse will return the original (\e lat, * \e lon) (to within roundoff). The routine does nothing if the origin * has not been set. **********************************************************************/ public void Forward(double lat, double lon, out double x, out double y, out double azi, out double rk) { if (!Init()) { x = double.NaN; y = double.NaN; azi = double.NaN; rk = double.NaN; } double e; double dlon = GeoMath.AngDiff(LongitudeOrigin(), lon, out e); double sig12, s12, azi1, azi2; sig12 = _earth.Inverse(lat, -Math.Abs(dlon), lat, Math.Abs(dlon), out s12, out azi1, out azi2); sig12 *= 0.5; s12 *= 0.5; if (s12 == 0) { double da = GeoMath.AngDiff(azi1, azi2, out e) / 2; if (Math.Abs(dlon) <= 90) { azi1 = 90 - da; azi2 = 90 + da; } else { azi1 = -90 - da; azi2 = -90 + da; } } if (dlon < 0) { azi2 = azi1; s12 = -s12; sig12 = -sig12; } x = s12; azi = GeoMath.AngNormalize(azi2); GeodesicLine perp = _earth.Line(lat, dlon, azi, GeodesicMask.GEODESICSCALE); double t; perp.GenPosition(true, -sig12, GeodesicMask.GEODESICSCALE, out t, out t, out t, out t, out t, out t, out rk, out t); double salp0, calp0; GeoMath.Sincosd(perp.EquatorialAzimuth(), out salp0, out calp0); double sbet1 = lat >= 0 ? calp0 : -calp0, cbet1 = Math.Abs(dlon) <= 90 ? Math.Abs(salp0) : -Math.Abs(salp0), sbet01 = sbet1 * _cbet0 - cbet1 * _sbet0, cbet01 = cbet1 * _cbet0 + sbet1 * _sbet0, sig01 = Math.Atan2(sbet01, cbet01) / GeoMath.Degree; _meridian.GenPosition(true, sig01, GeodesicMask.DISTANCE, out t, out t, out t, out y, out t, out t, out t, out t); }