コード例 #1
0
ファイル: geod_for.c プロジェクト: 20032334/route-me
	void
geod_for(void) {
	double d,sind,u,V,X,ds,cosds,sinds,ss,de;
	ss = 0.;
	
	if (ellipse) {
		d = geod_S / (D * geod_a);
		if (signS) d = -d;
		u = 2. * (s1 - d);
		V = cos(u + d);
		X = c2 * c2 * (sind = sin(d)) * cos(d) * (2. * V * V - 1.);
		ds = d + X - 2. * P * V * (1. - 2. * P * cos(u)) * sind;
		ss = s1 + s1 - ds;
	} else {
		ds = geod_S / geod_a;
		if (signS) ds = - ds;
	}
	cosds = cos(ds);
	sinds = sin(ds);
	if (signS) sinds = - sinds;
	al21 = N * cosds - sinth1 * sinds;
	if (merid) {
		phi2 = atan( tan(HALFPI + s1 - ds) / onef);
		if (al21 > 0.) {
			al21 = PI;
			if (signS)
				de = PI;
			else {
				phi2 = - phi2;
				de = 0.;
			}
		} else {
			al21 = 0.;
			if (signS) {
				phi2 = - phi2;
				de = 0;
			} else
				de = PI;
		}
	} else {
		al21 = atan(M / al21);
		if (al21 > 0)
			al21 += PI;
		if (al12 < 0.)
			al21 -= PI;
		al21 = adjlon(al21);
		phi2 = atan(-(sinth1 * cosds + N * sinds) * sin(al21) /
			(ellipse ? onef * M : M));
		de = atan2(sinds * sina12 ,
			(costh1 * cosds - sinth1 * sinds * cosa12));
		if (ellipse)
			if (signS)
				de += c1 * ((1. - c2) * ds +
					c2 * sinds * cos(ss));
			else
				de -= c1 * ((1. - c2) * ds -
					c2 * sinds * cos(ss));
	}
	lam2 = adjlon( lam1 + de );
}
コード例 #2
0
ファイル: tpeqd.hpp プロジェクト: TheRyaz/c_reading
void setup_tpeqd(Parameters& par, par_tpeqd& proj_parm)
{
    double lam_1, lam_2, phi_1, phi_2, A12, pp;
    /* get control point locations */
    phi_1 = pj_param(par.params, "rlat_1").f;
    lam_1 = pj_param(par.params, "rlon_1").f;
    phi_2 = pj_param(par.params, "rlat_2").f;
    lam_2 = pj_param(par.params, "rlon_2").f;
    if (phi_1 == phi_2 && lam_1 == lam_2) throw proj_exception(-25);
    par.lam0 = adjlon(0.5 * (lam_1 + lam_2));
    proj_parm.dlam2 = adjlon(lam_2 - lam_1);
    proj_parm.cp1 = cos(phi_1);
    proj_parm.cp2 = cos(phi_2);
    proj_parm.sp1 = sin(phi_1);
    proj_parm.sp2 = sin(phi_2);
    proj_parm.cs = proj_parm.cp1 * proj_parm.sp2;
    proj_parm.sc = proj_parm.sp1 * proj_parm.cp2;
    proj_parm.ccs = proj_parm.cp1 * proj_parm.cp2 * sin(proj_parm.dlam2);
    proj_parm.z02 = aacos(proj_parm.sp1 * proj_parm.sp2 + proj_parm.cp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
    proj_parm.hz0 = .5 * proj_parm.z02;
    A12 = atan2(proj_parm.cp2 * sin(proj_parm.dlam2),
                proj_parm.cp1 * proj_parm.sp2 - proj_parm.sp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
    proj_parm.ca = cos(pp = aasin(proj_parm.cp1 * sin(A12)));
    proj_parm.sa = sin(pp);
    proj_parm.lp = adjlon(atan2(proj_parm.cp1 * cos(A12), proj_parm.sp1) - proj_parm.hz0);
    proj_parm.dlam2 *= .5;
    proj_parm.lamc = HALFPI - atan2(sin(A12) * proj_parm.sp1, cos(A12)) - proj_parm.dlam2;
    proj_parm.thz0 = tan(proj_parm.hz0);
    proj_parm.rhshz0 = .5 / sin(proj_parm.hz0);
    proj_parm.r2z0 = 0.5 / proj_parm.z02;
    proj_parm.z02 *= proj_parm.z02;
    // par.inv = s_inverse;
    // par.fwd = s_forward;
    par.es = 0.;
}
コード例 #3
0
ファイル: pj_fwd.c プロジェクト: SvenGastauer/oce
	XY /* forward projection entry */
pj_fwd(LP lp, PJ *P) {
	XY xy;
	double t;

	/* check for forward and latitude or longitude overange */
	if ((t = fabs(lp.phi)-HALFPI) > EPS || fabs(lp.lam) > 10.) {
		xy.x = xy.y = HUGE_VAL;
		pj_ctx_set_errno( P->ctx, -14);
	} else { /* proceed with projection */
                P->ctx->last_errno = 0;
                pj_errno = 0;
                errno = 0;

		if (fabs(t) <= EPS)
			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
		else if (P->geoc)
			lp.phi = atan(P->rone_es * tan(lp.phi));
		lp.lam -= P->lam0;	/* compute del lp.lam */
		if (!P->over)
			lp.lam = adjlon(lp.lam); /* adjust del longitude */
		xy = (*P->fwd)(lp, P); /* project */
		if ( P->ctx->last_errno )
			xy.x = xy.y = HUGE_VAL;
		/* adjust for major axis and easting/northings */
		else {
			xy.x = P->fr_meter * (P->a * xy.x + P->x0);
			xy.y = P->fr_meter * (P->a * xy.y + P->y0);
		}
	}
	return xy;
}
コード例 #4
0
ファイル: proj_etmerc.c プロジェクト: Kitware/VTK
PJ *PROJECTION(utm) {
	int zone;
    struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
    if (0==Q)
        return freeup_new (P);
    P->opaque = Q;

	if (!P->es)
        E_ERROR(-34);
	P->y0 = pj_param (P->ctx, P->params, "bsouth").i ? 10000000. : 0.;
	P->x0 = 500000.;
	if (pj_param (P->ctx, P->params, "tzone").i) /* zone input ? */
		if ((zone = pj_param(P->ctx, P->params, "izone").i) > 0 && zone <= 60)
			--zone;
		else
			E_ERROR(-35)
	else /* nearest central meridian input */
		if ((zone = (int)(floor ((adjlon (P->lam0) + M_PI) * 30. / M_PI))) < 0)
			zone = 0;
		else if (zone >= 60)
			zone = 59;
	P->lam0 = (zone + .5) * M_PI / 30. - M_PI;
	P->k0 = 0.9996;
	P->phi0 = 0.;

    return setup (P);
}
コード例 #5
0
ファイル: PJ_tpeqd.c プロジェクト: Maasik/proj.4
PJ *PROJECTION(tpeqd) {
	double lam_1, lam_2, phi_1, phi_2, A12, pp;
    struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
    if (0==Q)
        return freeup_new (P);
    P->opaque = Q;


	/* get control point locations */
	phi_1 = pj_param(P->ctx, P->params, "rlat_1").f;
	lam_1 = pj_param(P->ctx, P->params, "rlon_1").f;
	phi_2 = pj_param(P->ctx, P->params, "rlat_2").f;
	lam_2 = pj_param(P->ctx, P->params, "rlon_2").f;

	if (phi_1 == phi_2 && lam_1 == lam_2)
        E_ERROR(-25);
	P->lam0  = adjlon (0.5 * (lam_1 + lam_2));
	Q->dlam2 = adjlon (lam_2 - lam_1);

	Q->cp1 = cos (phi_1);
	Q->cp2 = cos (phi_2);
	Q->sp1 = sin (phi_1);
	Q->sp2 = sin (phi_2);
	Q->cs = Q->cp1 * Q->sp2;
	Q->sc = Q->sp1 * Q->cp2;
	Q->ccs = Q->cp1 * Q->cp2 * sin(Q->dlam2);
	Q->z02 = aacos(P->ctx, Q->sp1 * Q->sp2 + Q->cp1 * Q->cp2 * cos (Q->dlam2));
	Q->hz0 = .5 * Q->z02;
	A12 = atan2(Q->cp2 * sin (Q->dlam2),
		Q->cp1 * Q->sp2 - Q->sp1 * Q->cp2 * cos (Q->dlam2));
	Q->ca = cos(pp = aasin(P->ctx, Q->cp1 * sin(A12)));
	Q->sa = sin(pp);
	Q->lp = adjlon ( atan2 (Q->cp1 * cos(A12), Q->sp1) - Q->hz0);
	Q->dlam2 *= .5;
	Q->lamc = M_HALFPI - atan2(sin(A12) * Q->sp1, cos(A12)) - Q->dlam2;
	Q->thz0 = tan (Q->hz0);
	Q->rhshz0 = .5 / sin (Q->hz0);
	Q->r2z0 = 0.5 / Q->z02;
	Q->z02 *= Q->z02;

    P->inv = s_inverse;
    P->fwd = s_forward;
	P->es = 0.;

    return P;
}
コード例 #6
0
ファイル: ob_tran.cpp プロジェクト: QuLogic/proj.4
static PJ_XY t_forward(PJ_LP lp, PJ *P) {             /* spheroid */
    struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
    double cosphi, coslam;

    cosphi = cos(lp.phi);
    coslam = cos(lp.lam);
    lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), sin(lp.phi)) + Q->lamp);
    lp.phi = aasin(P->ctx, - cosphi * coslam);

    return Q->link->fwd(lp, Q->link);
}
コード例 #7
0
ファイル: geod.c プロジェクト: jimmysoda/ogdi
	static void
do_arc(void) {
	double az;

	printLL(phi2, lam2); putchar('\n');
	for (az = al12; n_alpha--; ) {
		al12 = az = adjlon(az + del_alpha);
		geod_prefor();
		geod_forwd();
		printLL(phi2, lam2); putchar('\n');
	}
}
コード例 #8
0
ファイル: tpeqd.hpp プロジェクト: microcai/boost
            inline void setup_tpeqd(Params const& params, Parameters& par, par_tpeqd<T>& proj_parm)
            {
                T lam_1, lam_2, phi_1, phi_2, A12, pp;

                /* get control point locations */
                phi_1 = pj_get_param_r<T, srs::spar::lat_1>(params, "lat_1", srs::dpar::lat_1);
                lam_1 = pj_get_param_r<T, srs::spar::lon_1>(params, "lon_1", srs::dpar::lon_1);
                phi_2 = pj_get_param_r<T, srs::spar::lat_2>(params, "lat_2", srs::dpar::lat_2);
                lam_2 = pj_get_param_r<T, srs::spar::lon_2>(params, "lon_2", srs::dpar::lon_2);

                if (phi_1 == phi_2 && lam_1 == lam_2)
                    BOOST_THROW_EXCEPTION( projection_exception(error_control_point_no_dist) );

                par.lam0 = adjlon(0.5 * (lam_1 + lam_2));
                proj_parm.dlam2 = adjlon(lam_2 - lam_1);

                proj_parm.cp1 = cos(phi_1);
                proj_parm.cp2 = cos(phi_2);
                proj_parm.sp1 = sin(phi_1);
                proj_parm.sp2 = sin(phi_2);
                proj_parm.cs = proj_parm.cp1 * proj_parm.sp2;
                proj_parm.sc = proj_parm.sp1 * proj_parm.cp2;
                proj_parm.ccs = proj_parm.cp1 * proj_parm.cp2 * sin(proj_parm.dlam2);
                proj_parm.z02 = aacos(proj_parm.sp1 * proj_parm.sp2 + proj_parm.cp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
                proj_parm.hz0 = .5 * proj_parm.z02;
                A12 = atan2(proj_parm.cp2 * sin(proj_parm.dlam2),
                    proj_parm.cp1 * proj_parm.sp2 - proj_parm.sp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
                proj_parm.ca = cos(pp = aasin(proj_parm.cp1 * sin(A12)));
                proj_parm.sa = sin(pp);
                proj_parm.lp = adjlon(atan2(proj_parm.cp1 * cos(A12), proj_parm.sp1) - proj_parm.hz0);
                proj_parm.dlam2 *= .5;
                proj_parm.lamc = geometry::math::half_pi<T>() - atan2(sin(A12) * proj_parm.sp1, cos(A12)) - proj_parm.dlam2;
                proj_parm.thz0 = tan(proj_parm.hz0);
                proj_parm.rhshz0 = .5 / sin(proj_parm.hz0);
                proj_parm.r2z0 = 0.5 / proj_parm.z02;
                proj_parm.z02 *= proj_parm.z02;

                par.es = 0.;
            }
コード例 #9
0
ファイル: georef.c プロジェクト: AlexandreRio/route_pi
void geod_pre(void) {

    /*   Stuff the WGS84 projection parameters as necessary
    To avoid having to include <geodesic,h>
    */
    ellipse = 1;
    f = 1.0 / WGSinvf;       /* WGS84 ellipsoid flattening parameter */
    geod_a = WGS84_semimajor_axis_meters;

    es = 2 * f - f * f;
    onef = sqrt(1. - es);
    geod_f = 1 - onef;
    f2 = geod_f/2;
    f4 = geod_f/4;
    f64 = geod_f*geod_f/64;

    al12 = adjlon(al12); /* reduce to  +- 0-PI */
    signS = fabs(al12) > HALFPI ? 1 : 0;
    th1 = ellipse ? atan(onef * tan(phi1)) : phi1;
    costh1 = cos(th1);
    sinth1 = sin(th1);
    if ((merid = fabs(sina12 = sin(al12)) < MERI_TOL)) {
        sina12 = 0.;
        cosa12 = fabs(al12) < HALFPI ? 1. : -1.;
        M = 0.;
    } else {
        cosa12 = cos(al12);
        M = costh1 * sina12;
    }
    N = costh1 * cosa12;
    if (ellipse) {
        if (merid) {
            c1 = 0.;
            c2 = f4;
            D = 1. - c2;
            D *= D;
            P = c2 / D;
        } else {
            c1 = geod_f * M;
            c2 = f4 * (1. - M * M);
            D = (1. - c2)*(1. - c2 - c1 * M);
            P = (1. + .5 * c1 * M) * c2 / D;
        }
    }
    if (merid) s1 = HALFPI - th1;
    else {
        s1 = (fabs(M) >= 1.) ? 0. : acos(M);
        s1 =  sinth1 / sin(s1);
        s1 = (fabs(s1) >= 1.) ? 0. : acos(s1);
    }
}
コード例 #10
0
ファイル: fwd.cpp プロジェクト: QuLogic/proj.4
static PJ_COORD fwd_finalize (PJ *P, PJ_COORD coo) {

    switch (OUTPUT_UNITS) {

    /* Handle false eastings/northings and non-metric linear units */
    case PJ_IO_UNITS_CARTESIAN:

        if (P->is_geocent) {
            coo = proj_trans (P->cart, PJ_FWD, coo);
        }
        coo.xyz.x *= P->fr_meter;
        coo.xyz.y *= P->fr_meter;
        coo.xyz.z *= P->fr_meter;

        break;

    /* Classic proj.4 functions return plane coordinates in units of the semimajor axis */
    case PJ_IO_UNITS_CLASSIC:
        coo.xy.x *= P->a;
        coo.xy.y *= P->a;

    /* Falls through */ /* (<-- GCC warning silencer) */
    /* to continue processing in common with PJ_IO_UNITS_PROJECTED */
    case PJ_IO_UNITS_PROJECTED:
        coo.xyz.x = P->fr_meter  * (coo.xyz.x + P->x0);
        coo.xyz.y = P->fr_meter  * (coo.xyz.y + P->y0);
        coo.xyz.z = P->vfr_meter * (coo.xyz.z + P->z0);
        break;

    case PJ_IO_UNITS_WHATEVER:
        break;

    case PJ_IO_UNITS_RADIANS:
        coo.lpz.z = P->vfr_meter * (coo.lpz.z + P->z0);

        if( P->is_long_wrap_set ) {
            if( coo.lpz.lam != HUGE_VAL ) {
                coo.lpz.lam  = P->long_wrap_center +
                               adjlon(coo.lpz.lam - P->long_wrap_center);
            }
        }

        break;
    }

    if (P->axisswap)
        coo = proj_trans (P->axisswap, PJ_FWD, coo);

    return coo;
}
コード例 #11
0
ファイル: geod_for.c プロジェクト: Jalakas/libgarmin
void geod_pre(void)
{
    al12 = adjlon(al12);	/* reduce to +- 0-PI */
    signS = fabs(al12) > HALFPI ? 1 : 0;
    th1 = ellipse ? atan(onef * tan(phi1)) : phi1;
    costh1 = cos(th1);
    sinth1 = sin(th1);
    if ((merid = fabs(sina12 = sin(al12)) < MERI_TOL)) {
	sina12 = 0.;
	cosa12 = fabs(al12) < HALFPI ? 1. : -1.;
	M = 0.;
    } else {
	cosa12 = cos(al12);
	M = costh1 * sina12;
    }
    N = costh1 * cosa12;
    if (ellipse) {
	if (merid) {
	    c1 = 0.;
	    c2 = f4;
	    D = 1. - c2;
	    D *= D;
	    P = c2 / D;
	} else {
	    c1 = geod_f * M;
	    c2 = f4 * (1. - M * M);
	    D = (1. - c2) * (1. - c2 - c1 * M);
	    P = (1. + .5 * c1 * M) * c2 / D;
	}
    }
    if (merid)
	s1 = HALFPI - th1;
    else {
	s1 = (fabs(M) >= 1.) ? 0. : acos(M);
	s1 = sinth1 / sin(s1);
	s1 = (fabs(s1) >= 1.) ? 0. : acos(s1);
    }
}
コード例 #12
0
ファイル: pj_inv.c プロジェクト: AlbertDeFusco/pyproj
	LP /* inverse projection entry */
pj_inv(XY xy, PJ *P) {
	LP lp;

	/* can't do as much preliminary checking as with forward */
	if (xy.x == HUGE_VAL || xy.y == HUGE_VAL) {
		lp.lam = lp.phi = HUGE_VAL;
		pj_ctx_set_errno( P->ctx, -15);
                return lp;
	}

	errno = pj_errno = 0;
        P->ctx->last_errno = 0;

	xy.x = (xy.x * P->to_meter - P->x0) * P->ra; /* descale and de-offset */
	xy.y = (xy.y * P->to_meter - P->y0) * P->ra;

        //Check for NULL pointer
        if (P->inv != NULL)
        {
	    lp = (*P->inv)(xy, P); /* inverse project */
	    if (P->ctx->last_errno )
		lp.lam = lp.phi = HUGE_VAL;
	    else {
		lp.lam += P->lam0; /* reduce from del lp.lam */
		if (!P->over)
			lp.lam = adjlon(lp.lam); /* adjust longitude to CM */
		if (P->geoc && fabs(fabs(lp.phi)-HALFPI) > EPS)
			lp.phi = atan(P->one_es * tan(lp.phi));
	    }
        }
        else
        {
           lp.lam = lp.phi = HUGE_VAL;
        }
	return lp;
}
コード例 #13
0
ファイル: pj_factors.c プロジェクト: dyang02/SurrogateTools
	int
pj_factors(LP lp, PJ *P, double h, struct FACTORS *fac) {
	struct DERIVS der;
	double cosphi, t, n, r;

	/* check for forward and latitude or longitude overange */
	if ((t = fabs(lp.phi)-HALFPI) > EPS || fabs(lp.lam) > 10.) {
		pj_errno = -14;
		return 1;
	} else { /* proceed */
		errno = pj_errno = 0;
		if (fabs(t) <= EPS) /* adjust to pi/2 */
			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
		else if (P->geoc)
			lp.phi = atan(P->rone_es * tan(lp.phi));
		lp.lam -= P->lam0;	/* compute del lp.lam */
		if (!P->over)
			lp.lam = adjlon(lp.lam); /* adjust del longitude */
		if (h <= 0.)
			h = DEFAULT_H;
		if (P->spc)	/* get what projection analytic values */
			P->spc(lp, P, fac);
		if (((fac->code & (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) !=
			  (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) &&
			  pj_deriv(lp, h, P, &der))
			return 1;
		if (!(fac->code & IS_ANAL_XL_YL)) {
			fac->der.x_l = der.x_l;
			fac->der.y_l = der.y_l;
		}
		if (!(fac->code & IS_ANAL_XP_YP)) {
			fac->der.x_p = der.x_p;
			fac->der.y_p = der.y_p;
		}
		cosphi = cos(lp.phi);
		if (!(fac->code & IS_ANAL_HK)) {
			fac->h = hypot(fac->der.x_p, fac->der.y_p);
			fac->k = hypot(fac->der.x_l, fac->der.y_l) / cosphi;
			if (P->es) {
				t = sin(lp.phi);
				t = 1. - P->es * t * t;
				n = sqrt(t);
				fac->h *= t * n / P->one_es;
				fac->k *= n;
				r = t * t / P->one_es;
			} else
				r = 1.;
		} else if (P->es) {
			r = sin(lp.phi);
			r = 1. - P->es * r * r;
			r = r * r / P->one_es;
		} else
			r = 1.;
		/* convergence */
		if (!(fac->code & IS_ANAL_CONV)) {
			fac->conv = - atan2(fac->der.y_l, fac->der.x_l);
			if (fac->code & IS_ANAL_XL_YL)
				fac->code |= IS_ANAL_CONV;
		}
		/* areal scale factor */
		fac->s = (fac->der.y_p * fac->der.x_l - fac->der.x_p * fac->der.y_l) *
			r / cosphi;
		/* meridian-parallel angle theta prime */
		fac->thetap = aasin(fac->s / (fac->h * fac->k));
		/* Tissot ellips axis */
		t = fac->k * fac->k + fac->h * fac->h;
		fac->a = sqrt(t + 2. * fac->s);
		t = (t = t - 2. * fac->s) <= 0. ? 0. : sqrt(t);
		fac->b = 0.5 * (fac->a - t);
		fac->a = 0.5 * (fac->a + t);
		/* omega */
		fac->omega = 2. * aasin((fac->a - fac->b)/(fac->a + fac->b));
	}
	return 0;
}
コード例 #14
0
	LP
nad_cvt(LP in, int inverse, struct CTABLE *ct) {
	LP t, tb;

	if (in.lam == HUGE_VAL)
		return in;
	/* normalize input to ll origin */
	tb = in;
	tb.lam -= ct->ll.lam;
	tb.phi -= ct->ll.phi;
	tb.lam = adjlon(tb.lam);
	t = nad_intr(tb, ct);
	if (inverse) {
		LP del, dif;
		int i = MAX_TRY;

		if (t.lam == HUGE_VAL) return t;
		t.lam = tb.lam + t.lam;
		t.phi = tb.phi - t.phi;

		do {
			del = nad_intr(t, ct);

                        /* 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.lam == HUGE_VAL) 
                        {
                            if( getenv( "PROJ_DEBUG" ) != NULL )
                                fprintf( stderr, 
                                         "Inverse grid shift iteration failed, presumably at grid edge.\n"
                                         "Using first approximation.\n" );
                            /* return del */;
                            break;
                        }

			t.lam -= dif.lam = t.lam - del.lam - tb.lam;
			t.phi -= dif.phi = t.phi + del.phi - tb.phi;
		} while (i-- && fabs(dif.lam) > TOL && fabs(dif.phi) > TOL);
		if (i < 0) {
                    if( getenv( "PROJ_DEBUG" ) != NULL )
                        fprintf( stderr, 
                                 "Inverse grid shift iterator failed to converge.\n" );
                    t.lam = t.phi = HUGE_VAL;
                    return t;
		}
		in.lam = adjlon(t.lam + ct->ll.lam);
		in.phi = t.phi + ct->ll.phi;
	} else {
		if (t.lam == HUGE_VAL)
			in = t;
		else {
			in.lam -= t.lam;
			in.phi += t.phi;
		}
	}
	return in;
}
コード例 #15
0
ファイル: NavFunc.cpp プロジェクト: Rasbats/DR_pi
double DistGreatCircle(double slat, double slon, double dlat, double dlon)
{
	//    double th1,costh1,sinth1,sina12,cosa12,M,N,c1,c2,D,P,s1;
	//    int merid, signS;

	//   Input/Output from geodesic functions
	double al12;           // Forward azimuth
	double al21;           // Back azimuth
	double geod_S;         // Distance
	double phi1, lam1, phi2, lam2;

	int ellipse;
	double geod_f;
	double geod_a;
	double es, onef, f, f64, f2, f4;

	double d5;
	phi1 = slat * DEGREE;
	lam1 = slon * DEGREE;
	phi2 = dlat * DEGREE;
	lam2 = dlon * DEGREE;

	//void geod_inv(struct georef_state *state)
	{
		double      th1, th2, thm, dthm, dlamm, dlam, sindlamm, costhm, sinthm, cosdthm,
			sindthm, L, E, cosd, d, X, Y, T, sind, tandlammp, u, v, D, A, B;


		//   Stuff the WGS84 projection parameters as necessary
		//      To avoid having to include <geodesic,h>
		//

		ellipse = 1;
		f = 1.0 / WGSinvf;       // WGS84 ellipsoid flattening parameter //
		geod_a = WGS84_semimajor_axis_meters;

		es = 2 * f - f * f;
		onef = sqrt(1. - es);
		geod_f = 1 - onef;
		f2 = geod_f / 2;
		f4 = geod_f / 4;
		f64 = geod_f*geod_f / 64;


		if (ellipse) {
			th1 = atan(onef * tan(phi1));
			th2 = atan(onef * tan(phi2));
		}
		else {
			th1 = phi1;
			th2 = phi2;
		}
		thm = .5 * (th1 + th2);
		dthm = .5 * (th2 - th1);
		dlamm = .5 * (dlam = adjlon(lam2 - lam1));
		if (fabs(dlam) < DTOL && fabs(dthm) < DTOL) {
			al12 = al21 = geod_S = 0.;
			return 0.0;
		}
		sindlamm = sin(dlamm);
		costhm = cos(thm);      sinthm = sin(thm);
		cosdthm = cos(dthm);    sindthm = sin(dthm);
		L = sindthm * sindthm + (cosdthm * cosdthm - sinthm * sinthm)
			* sindlamm * sindlamm;
		d = acos(cosd = 1 - L - L);
		if (ellipse) {
			E = cosd + cosd;
			sind = sin(d);
			Y = sinthm * cosdthm;
			Y *= (Y + Y) / (1. - L);
			T = sindthm * costhm;
			T *= (T + T) / L;
			X = Y + T;
			Y -= T;
			T = d / sind;
			D = 4. * T * T;
			A = D * E;
			B = D + D;
			geod_S = geod_a * sind * (T - f4 * (T * X - Y) +
				f64 * (X * (A + (T - .5 * (A - E)) * X) -
				Y * (B + E * Y) + D * X * Y));
			tandlammp = tan(.5 * (dlam - .25 * (Y + Y - E * (4. - X)) *
				(f2 * T + f64 * (32. * T - (20. * T - A)
				* X - (B + 4.) * Y)) * tan(dlam)));
		}
		else {
			geod_S = geod_a * d;
			tandlammp = tan(dlamm);
		}
		u = atan2(sindthm, (tandlammp * costhm));
		v = atan2(cosdthm, (tandlammp * sinthm));
		al12 = adjlon(TWOPI + v - u);
		al21 = adjlon(TWOPI - v - u);
	}

	d5 = geod_S / 1852.0;

	return d5;
}
コード例 #16
0
ファイル: PJ_ob_tran.c プロジェクト: fb/jasper-xcsoar
#include <string.h>
PROJ_HEAD(ob_tran, "General Oblique Transformation") "\n\tMisc Sph"
"\n\to_proj= plus parameters for projection"
"\n\to_lat_p= o_lon_p= (new pole) or"
"\n\to_alpha= o_lon_c= o_lat_c= or"
"\n\to_lon_1= o_lat_1= o_lon_2= o_lat_2=";
#define TOL 1e-10
FORWARD(o_forward); /* spheroid */
	double coslam, sinphi, cosphi;

        (void) xy;

	coslam = cos(lp.lam);
	sinphi = sin(lp.phi);
	cosphi = cos(lp.phi);
	lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), P->sphip * cosphi * coslam +
		P->cphip * sinphi) + P->lamp);
	lp.phi = aasin(P->sphip * sinphi - P->cphip * cosphi * coslam);
	return (P->link->fwd(lp, P->link));
}
FORWARD(t_forward); /* spheroid */
	double cosphi, coslam;

        (void) xy;

	cosphi = cos(lp.phi);
	coslam = cos(lp.lam);
	lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), sin(lp.phi)) + P->lamp);
	lp.phi = aasin(- cosphi * coslam);
	return (P->link->fwd(lp, P->link));
}
INVERSE(o_inverse); /* spheroid */
コード例 #17
0
ファイル: georef.c プロジェクト: AlexandreRio/route_pi
void geod_inv() {
    double      th1,th2,thm,dthm,dlamm,dlam,sindlamm,costhm,sinthm,cosdthm,
                sindthm,L,E,cosd,d,X,Y,T,sind,tandlammp,u,v,D,A,B;


    /*   Stuff the WGS84 projection parameters as necessary
    To avoid having to include <geodesic,h>
    */

    ellipse = 1;
    f = 1.0 / WGSinvf;       /* WGS84 ellipsoid flattening parameter */
    geod_a = WGS84_semimajor_axis_meters;

    es = 2 * f - f * f;
    onef = sqrt(1. - es);
    geod_f = 1 - onef;
    f2 = geod_f/2;
    f4 = geod_f/4;
    f64 = geod_f*geod_f/64;


    if (ellipse) {
        th1 = atan(onef * tan(phi1));
        th2 = atan(onef * tan(phi2));
    } else {
        th1 = phi1;
        th2 = phi2;
    }
    thm = .5 * (th1 + th2);
    dthm = .5 * (th2 - th1);
    dlamm = .5 * ( dlam = adjlon(lam2 - lam1) );
    if (fabs(dlam) < DTOL && fabs(dthm) < DTOL) {
        al12 =  al21 = geod_S = 0.;
        return;
    }
    sindlamm = sin(dlamm);
    costhm = cos(thm);
    sinthm = sin(thm);
    cosdthm = cos(dthm);
    sindthm = sin(dthm);
    L = sindthm * sindthm + (cosdthm * cosdthm - sinthm * sinthm)
        * sindlamm * sindlamm;
    d = acos(cosd = 1 - L - L);
    if (ellipse) {
        E = cosd + cosd;
        sind = sin( d );
        Y = sinthm * cosdthm;
        Y *= (Y + Y) / (1. - L);
        T = sindthm * costhm;
        T *= (T + T) / L;
        X = Y + T;
        Y -= T;
        T = d / sind;
        D = 4. * T * T;
        A = D * E;
        B = D + D;
        geod_S = geod_a * sind * (T - f4 * (T * X - Y) +
                                  f64 * (X * (A + (T - .5 * (A - E)) * X) -
                                         Y * (B + E * Y) + D * X * Y));
        tandlammp = tan(.5 * (dlam - .25 * (Y + Y - E * (4. - X)) *
                              (f2 * T + f64 * (32. * T - (20. * T - A)
                                               * X - (B + 4.) * Y)) * tan(dlam)));
    } else {
        geod_S = geod_a * d;
        tandlammp = tan(dlamm);
    }
    u = atan2(sindthm , (tandlammp * costhm));
    v = atan2(cosdthm , (tandlammp * sinthm));
    al12 = adjlon(TWOPI + v - u);
    al21 = adjlon(TWOPI - v - u);
}
コード例 #18
0
ファイル: pj_factors.c プロジェクト: ampimis/RtkGps
int pj_factors(LP lp, const PJ *P, double h, struct FACTORS *fac) {
    double cosphi, t, n, r;
    int err;
    PJ_COORD coo = {{0, 0, 0, 0}};
    coo.lp = lp;

    /* Failing the 3 initial checks will most likely be due to */
    /* earlier errors, so we leave errno alone */
    if (0==fac)
        return 1;

    if (0==P)
        return 1;

    if (HUGE_VAL==lp.lam)
        return 1;

    /* But from here, we're ready to make our own mistakes */
    err = proj_errno_reset (P);

    /* Indicate that all factors are numerical approximations */
    fac->code = 0;

    /* Check for latitude or longitude overange */
    if ((fabs (lp.phi)-M_HALFPI) > EPS || fabs (lp.lam) > 10.) {
        proj_errno_set (P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT);
        return 1;
    }

    /* Set a reasonable step size for the numerical derivatives */
    h = fabs (h);
    if (h < EPS)
        h = DEFAULT_H;

    /* If input latitudes are geocentric, convert to geographic */
    if (P->geoc)
        lp = proj_geocentric_latitude (P, PJ_INV, coo).lp;

    /* If latitude + one step overshoots the pole, move it slightly inside, */
    /* so the numerical derivative still exists */
    if (fabs (lp.phi) > (M_HALFPI - h))
        lp.phi = lp.phi < 0. ? -(M_HALFPI-h) : (M_HALFPI-h);

    /* Longitudinal distance from central meridian */
    lp.lam -= P->lam0;
    if (!P->over)
        lp.lam = adjlon(lp.lam);

    /* Derivatives */
    if (pj_deriv (lp, h, P, &(fac->der))) {
        proj_errno_set (P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT);
        return 1;
    }

    /* Scale factors */
    cosphi = cos (lp.phi);
    fac->h = hypot (fac->der.x_p, fac->der.y_p);
    fac->k = hypot (fac->der.x_l, fac->der.y_l) / cosphi;

    if (P->es != 0.0) {
        t = sin(lp.phi);
        t = 1. - P->es * t * t;
        n = sqrt(t);
        fac->h *= t * n / P->one_es;
        fac->k *= n;
        r = t * t / P->one_es;
    } else
        r = 1.;

    /* Convergence */
    fac->conv = -atan2 (fac->der.x_p, fac->der.y_p);

    /* Areal scale factor */
    fac->s = (fac->der.y_p * fac->der.x_l - fac->der.x_p * fac->der.y_l) * r / cosphi;

    /* Meridian-parallel angle (theta prime) */
    fac->thetap = aasin(P->ctx,fac->s / (fac->h * fac->k));

    /* Tissot ellipse axis */
    t = fac->k * fac->k + fac->h * fac->h;
    fac->a = sqrt(t + 2. * fac->s);
    t = t - 2. * fac->s;
    t = t > 0? sqrt(t): 0;
    fac->b = 0.5 * (fac->a - t);
    fac->a = 0.5 * (fac->a + t);

    /* Angular distortion */
    fac->omega = 2. * aasin(P->ctx, (fac->a - fac->b) / (fac->a + fac->b) );

    proj_errno_restore (P, err);
    return 0;
}
コード例 #19
0
ファイル: fwd.cpp プロジェクト: QuLogic/proj.4
static PJ_COORD fwd_prepare (PJ *P, PJ_COORD coo) {
    if (HUGE_VAL==coo.v[0] || HUGE_VAL==coo.v[1] || HUGE_VAL==coo.v[2])
        return proj_coord_error ();

    /* The helmert datum shift will choke unless it gets a sensible 4D coordinate */
    if (HUGE_VAL==coo.v[2] && P->helmert) coo.v[2] = 0.0;
    if (HUGE_VAL==coo.v[3] && P->helmert) coo.v[3] = 0.0;

    /* Check validity of angular input coordinates */
    if (INPUT_UNITS==PJ_IO_UNITS_RADIANS) {
        double t;

        /* check for latitude or longitude over-range */
        t = (coo.lp.phi < 0  ?  -coo.lp.phi  :  coo.lp.phi) - M_HALFPI;
        if (t > PJ_EPS_LAT  ||  coo.lp.lam > 10  ||  coo.lp.lam < -10) {
            proj_errno_set (P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT);
            return proj_coord_error ();
        }

        /* Clamp latitude to -90..90 degree range */
        if (coo.lp.phi > M_HALFPI)
            coo.lp.phi = M_HALFPI;
        if (coo.lp.phi < -M_HALFPI)
            coo.lp.phi = -M_HALFPI;

        /* If input latitude is geocentrical, convert to geographical */
        if (P->geoc)
            coo = pj_geocentric_latitude (P, PJ_INV, coo);

        /* Ensure longitude is in the -pi:pi range */
        if (0==P->over)
            coo.lp.lam = adjlon(coo.lp.lam);

        if (P->hgridshift)
            coo = proj_trans (P->hgridshift, PJ_INV, coo);
        else if (P->helmert || (P->cart_wgs84 != nullptr && P->cart != nullptr)) {
            coo = proj_trans (P->cart_wgs84, PJ_FWD, coo); /* Go cartesian in WGS84 frame */
            if( P->helmert )
                coo = proj_trans (P->helmert,    PJ_INV, coo); /* Step into local frame */
            coo = proj_trans (P->cart,       PJ_INV, coo); /* Go back to angular using local ellps */
        }
        if (coo.lp.lam==HUGE_VAL)
            return coo;
        if (P->vgridshift)
            coo = proj_trans (P->vgridshift, PJ_FWD, coo); /* Go orthometric from geometric */

        /* Distance from central meridian, taking system zero meridian into account */
        coo.lp.lam = (coo.lp.lam - P->from_greenwich) - P->lam0;

        /* Ensure longitude is in the -pi:pi range */
        if (0==P->over)
            coo.lp.lam = adjlon(coo.lp.lam);

        return coo;
    }


    /* We do not support gridshifts on cartesian input */
    if (INPUT_UNITS==PJ_IO_UNITS_CARTESIAN && P->helmert)
            return proj_trans (P->helmert, PJ_INV, coo);
    return coo;
}