コード例 #1
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;
}
コード例 #2
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;
}