void geod_lineinit_int(geod_geodesic g, double lat1, double lon1, double azi1, double salp1, double calp1, GEOD caps) { a = g.a; f = g.f; b = g.b; c2 = g.c2; f1 = g.f1; // If caps is 0 assume the standard direct calculation this.caps = (caps != 0 ? caps : GEOD.DISTANCE_IN | GEOD.LONGITUDE) | GEOD.LATITUDE | GEOD.AZIMUTH | GEOD.LONG_UNROLL; // always allow latitude and azimuth and unrolling of longitude this.lat1 = LatFix(lat1); this.lon1 = lon1; this.azi1 = azi1; this.salp1 = salp1; this.calp1 = calp1; double cbet1, sbet1; sincosdx(AngRound(lat1), out sbet1, out cbet1); sbet1 *= f1; // Ensure cbet1 = +epsilon at poles norm2(ref sbet1, ref cbet1); cbet1 = maxx(tiny, cbet1); dn1 = Math.Sqrt(1 + g.ep2 * sq(sbet1)); // Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0), salp0 = salp1 * cbet1; // alp0 in [0, pi/2 - |bet1|] // Alt: calp0 = hypot(sbet1, calp1 * cbet1). The following // is slightly better (consider the case salp1 = 0). calp0 = hypotx(calp1, salp1 * sbet1); // Evaluate sig with tan(bet1) = tan(sig1) * cos(alp1). // sig = 0 is nearest northward crossing of equator. // With bet1 = 0, alp1 = pi/2, we have sig1 = 0 (equatorial line). // With bet1 = pi/2, alp1 = -pi, sig1 = pi/2 // With bet1 = -pi/2, alp1 = 0 , sig1 = -pi/2 // Evaluate omg1 with tan(omg1) = sin(alp0) * tan(sig1). // With alp0 in (0, pi/2], quadrants for sig and omg coincide. // No atan2(0,0) ambiguity at poles since cbet1 = +epsilon. // With alp0 = 0, omg1 = 0 for alp1 = 0, omg1 = pi for alp1 = pi. ssig1 = sbet1; somg1 = salp0 * sbet1; csig1 = comg1 = sbet1 != 0 || calp1 != 0 ? cbet1 * calp1 : 1; norm2(ref ssig1, ref csig1); // sig1 in (-pi, pi] // norm2(somg1, comg1); -- don't need to normalize! k2 = sq(calp0) * g.ep2; double eps = k2 / (2 * (1 + Math.Sqrt(1 + k2)) + k2); if ((this.caps & GEOD.CAP_C1) != 0) { double s, c; A1m1 = geod_geodesic.A1m1f(eps); geod_geodesic.C1f(eps, C1a); B11 = SinCosSeries(true, ssig1, csig1, C1a, nC1); s = Math.Sin(B11); c = Math.Cos(B11); // tau1=sig1+B11 stau1 = ssig1 * c + csig1 * s; ctau1 = csig1 * c - ssig1 * s; // Not necessary because C1pa reverts C1a // B11=-SinCosSeries(TRUE, stau1, ctau1, C1pa, nC1p); } if ((this.caps & GEOD.CAP_C1p) != 0) geod_geodesic.C1pf(eps, C1pa); if ((this.caps & GEOD.CAP_C2) != 0) { A2m1 = geod_geodesic.A2m1f(eps); geod_geodesic.C2f(eps, C2a); B21 = SinCosSeries(true, ssig1, csig1, C2a, nC2); } if ((this.caps & GEOD.CAP_C3) != 0) { g.C3f(eps, C3a); A3c = -f * salp0 * g.A3f(eps); B31 = SinCosSeries(true, ssig1, csig1, C3a, nC3 - 1); } if ((this.caps & GEOD.CAP_C4) != 0) { g.C4f(eps, C4a); // Multiplier=a^2*e^2*cos(alpha0)*sin(alpha0) A4 = sq(a) * calp0 * salp0 * g.e2; B41 = SinCosSeries(false, ssig1, csig1, C4a, nC4); } a13 = s13 = double.NaN; }
public override PJ Init() { g=new geod_geodesic(a, es/(1+Math.Sqrt(one_es))); phi0=Proj.pj_param_r(ctx, parameters, "lat_0"); if(Math.Abs(Math.Abs(phi0)-Proj.HALFPI)<EPS10) { mode=phi0<0.0?aeqd_mode.S_POLE:aeqd_mode.N_POLE; sinph0=phi0<0.0?-1.0:1.0; cosph0=0.0; } else if(Math.Abs(phi0)<EPS10) { mode=aeqd_mode.EQUIT; sinph0=0.0; cosph0=1.0; } else { mode=aeqd_mode.OBLIQ; sinph0=Math.Sin(phi0); cosph0=Math.Cos(phi0); } if(es==0) { inv=s_inverse; fwd=s_forward; } else { en=Proj.pj_enfn(es); if(en==null) return null; if(Proj.pj_param_b(ctx, parameters, "guam")) { M1=Proj.pj_mlfn(phi0, sinph0, cosph0, en); inv=e_guam_inv; fwd=e_guam_fwd; } else { switch(mode) { case aeqd_mode.N_POLE: Mp=Proj.pj_mlfn(Proj.HALFPI, 1.0, 0.0, en); break; case aeqd_mode.S_POLE: Mp=Proj.pj_mlfn(-Proj.HALFPI, -1.0, 0.0, en); break; case aeqd_mode.EQUIT: case aeqd_mode.OBLIQ: inv=e_inverse; fwd=e_forward; N1=1.0/Math.Sqrt(1.0-es*sinph0*sinph0); He=e/Math.Sqrt(one_es); G=sinph0*He; He*=cosph0; break; } inv=e_inverse; fwd=e_forward; } } return this; }
/// <summary> /// Initialize a geod_geodesicline object in terms of the inverse geodesic problem. /// </summary> /// <param name="g">The <see cref="geod_geodesic"/> object specifying the ellipsoid.</param> /// <param name="lat1">Latitude of point 1 (degrees).</param> /// <param name="lon1">Longitude of point 1 (degrees).</param> /// <param name="lat2">Latitude of point 2 (degrees).</param> /// <param name="lon2">Longitude of point 2 (degrees).</param> /// <param name="caps">Bitor'ed combination of <see cref="geod_mask"/> values. See remarks for more informations.</param> /// <remarks> /// <paramref name="caps"/> bitor'ed combination of geod_mask() values specifying /// the capabilities the geod_geodesicline object should possess, i.e., which /// quantities can be returned in calls to geod_position() and /// geod_genposition(). /// /// This function sets point 3 of the geod_geodesicline to correspond to point /// 2 of the direct geodesic problem. See geod_lineinit() for more /// information. /// </remarks> public void geod_inverseline(geod_geodesic g, double lat1, double lon1, double lat2, double lon2, GEOD caps) { double salp1, calp1, dummy; double a12 = g.geod_geninverse_int(lat1, lon1, lat2, lon2, out dummy, out salp1, out calp1, out dummy, out dummy, out dummy, out dummy, out dummy, out dummy); double azi1 = atan2dx(salp1, calp1); caps = caps != 0 ? caps : GEOD.DISTANCE_IN | GEOD.LONGITUDE; // Ensure that a12 can be converted to a distance if ((caps & (GEOD.OUT_ALL & GEOD.DISTANCE_IN)) != 0) caps |= GEOD.DISTANCE; geod_lineinit_int(g, lat1, lon1, azi1, salp1, calp1, caps); geod_setarc(a12); }
/// <summary> /// geod_gendirectline : Initialize a geod_geodesicline object in terms of the direct geodesic /// problem specified in terms of either distance or arc length. /// </summary> /// <param name="g">The <see cref="geod_geodesic"/> object specifying the ellipsoid.</param> /// <param name="lat1">Latitude of point 1 (degrees).</param> /// <param name="lon1">Longitude of point 1 (degrees).</param> /// <param name="azi1">Azimuth at point 1 (degrees).</param> /// <param name="flags">Must be either <see cref="GEOD.NOFLAGS"/> or <see cref="GEOD.ARCMODE"/> to determining the meaning of the <paramref name="s12_a12"/>.</param> /// <param name="s12_a12">if <paramref name="flags"/> = <see cref="GEOD.NOFLAGS"/>, this is the distance from point 1 to point 2 (meters); /// if <paramref name="flags"/> = <see cref="GEOD.ARCMODE"/>, it is the arc length from point 1 to point 2 (degrees); it can be negative.</param> /// <param name="caps">Bitor'ed combination of <see cref="geod_mask"/> values. See remarks for more informations.</param> /// <remarks> /// <paramref name="caps"/> bitor'ed combination of geod_mask() values specifying /// the capabilities the geod_geodesicline object should possess, i.e., which /// quantities can be returned in calls to geod_position() and /// geod_genposition(). /// /// This function sets point 3 of the geod_geodesicline to correspond to point /// 2 of the direct geodesic problem. See geod_lineinit() for more /// information. /// </remarks> public geod_geodesicline(geod_geodesic g, double lat1, double lon1, double azi1, GEOD flags, double s12_a12, GEOD caps) : this(g, lat1, lon1, azi1, caps) { geod_gensetdistance(flags, s12_a12); }
/// <summary> /// geod_directline : Initialize a geod_geodesicline object in terms of the direct geodesic problem. /// </summary> /// <param name="g">The <see cref="geod_geodesic"/> object specifying the ellipsoid.</param> /// <param name="lat1">Latitude of point 1 (degrees).</param> /// <param name="lon1">Longitude of point 1 (degrees).</param> /// <param name="azi1">Azimuth at point 1 (degrees).</param> /// <param name="s12">Distance from point 1 to point 2 (meters); it can be negative.</param> /// <param name="caps">Bitor'ed combination of <see cref="geod_mask"/> values. See remarks for more informations.</param> /// <remarks> /// <paramref name="caps"/> bitor'ed combination of geod_mask() values specifying /// the capabilities the geod_geodesicline object should possess, i.e., which /// quantities can be returned in calls to geod_position() and /// geod_genposition(). /// /// This function sets point 3 of the geod_geodesicline to correspond to point /// 2 of the direct geodesic problem. See geod_lineinit() for more /// information. /// </remarks> public geod_geodesicline(geod_geodesic g, double lat1, double lon1, double azi1, double s12, GEOD caps) : this(g, lat1, lon1, azi1, GEOD.NOFLAGS, s12, caps) { }
/// <summary> /// geod_lineinit : Initialize a geod_geodesicline object. /// </summary> /// <param name="g">The <see cref="geod_geodesic"/> object specifying the ellipsoid.</param> /// <param name="lat1">Latitude of point 1 (degrees).</param> /// <param name="lon1">Longitude of point 1 (degrees).</param> /// <param name="azi1">Azimuth at point 1 (degrees).</param> /// <param name="caps">Bitor'ed combination of <see cref="geod_mask"/> values. See remarks for more informations.</param> /// <remarks> /// <paramref name="caps"/> bitor'ed combination of geod_mask() values specifying /// the capabilities the geod_geodesicline object should possess, i.e., which /// quantities can be returned in calls to geod_position() and /// geod_genposition(). /// /// <paramref name="lat1"/> should be in the range [-90deg, 90deg]. /// /// The geod_mask values are: /// - caps|=GEOD_LATITUDE for the latitude lat2; this is added automatically, /// - caps|=GEOD_LONGITUDE for the latitude lon2, /// - caps|=GEOD_AZIMUTH for the latitude azi2; this is added automatically, /// - caps|=GEOD_DISTANCE for the distance s12, /// - caps|=GEOD_REDUCEDLENGTH for the reduced length m12, /// - caps|=GEOD_GEODESICSCALE for the geodesic scales M12 and M21, /// - caps|=GEOD_AREA for the area S12, /// - caps|=GEOD_DISTANCE_IN permits the length of the /// geodesic to be given in terms of s12; without this capability the /// length can only be specified in terms of arc length. /// /// A value of caps=0 is treated as GEOD.LATITUDE|GEOD.LONGITUDE|GEOD.AZIMUTH|GEOD.DISTANCE_IN /// (to support the solution of the "standard" direct problem). /// /// When initialized by this function, point 3 is undefined (s13 = a13 = NaN). /// </remarks> public geod_geodesicline(geod_geodesic g, double lat1, double lon1, double azi1, GEOD caps) { azi1 = AngNormalize(azi1); double salp1, calp1; // Guard against underflow in salp0 sincosdx(AngRound(azi1), out salp1, out calp1); geod_lineinit_int(g, lat1, lon1, azi1, salp1, calp1, caps); }
public void Ini() { GlobalGeodesic = new geod_geodesic(geod_a, geod_f); }