Ejemplo n.º 1
0
	double
dmstor(const char *is, char **rs) {
	int sign, n, nl;
	char *p, *s, work[MAX_WORK];
	double v, tv;

	if (rs)
		*rs = (char *)is;
	/* copy sting into work space */
	while (isspace(sign = *is)) ++is;
	for (n = MAX_WORK, s = work, p = (char *)is; isgraph(*p) && --n ; )
		*s++ = *p++;
	*s = '\0';
	/* it is possible that a really odd input (like lots of leading
		zeros) could be truncated in copying into work.  But ... */
	sign = *(s = work);
	if (sign == '+' || sign == '-') s++;
	else sign = '+';
	for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) {
		if (!(isdigit(*s) || *s == '.')) break;
		if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
			return tv;
		switch (*s) {
		case 'D': case 'd':
			n = 0; break;
		case '\'':
			n = 1; break;
		case '"':
			n = 2; break;
		case 'r': case 'R':
			if (nl) {
				pj_errno = -16;
				return HUGE_VAL;
			}
			++s;
			v = tv;
			goto skip;
		default:
			v += tv * vm[nl];
		skip:	n = 4;
			continue;
		}
		if (n < nl) {
			pj_errno = -16;
			return HUGE_VAL;
		}
		v += tv * vm[n];
		++s;
	}
		/* postfix sign */
	if (*s && (p = strchr(sym, *s))) {
		sign = (p - sym) >= 4 ? '-' : '+';
		++s;
	}
	if (sign == '-')
		v = -v;
	if (rs) /* return point of next char after valid string */
		*rs = (char *)is + (s - work);
	return v;
}
Ejemplo n.º 2
0
static PJ_COORD parse_coord (const char *args) {
/*****************************************************************************
Attempt to interpret args as a PJ_COORD.
******************************************************************************/
    int i;
    const char *endp;
    const char *dmsendp;
    const char *prev = args;
    PJ_COORD a = proj_coord (0,0,0,0);

    T.dimensions_given = 0;
    for (i = 0;   i < 4;   i++) {
        /* proj_strtod doesn't read values like 123d45'678W so we need a bit */
        /* of help from proj_dmstor. proj_strtod effectively ignores what    */
        /* comes after "d", so we use that fact that when dms is larger than */
        /* d the value was stated in "dms" form.                             */
        /* This could be avoided if proj_dmstor used the same proj_strtod()  */
        /* as gie, but that is not the case (yet). When we remove projects.h */
        /* from the public API we can change that.                           */
        double d = proj_strtod(prev,  (char **) &endp);
        double dms = PJ_TODEG(proj_dmstor (prev, (char **) &dmsendp));
       /* TODO: When projects.h is removed, call proj_dmstor() in all cases */
        if (d != dms && fabs(d) < fabs(dms) && fabs(dms) < fabs(d) + 1) {
            d = dms;
            endp = dmsendp;
        }
        /* A number like -81d00'00.000 will be parsed correctly by both */
        /* proj_strtod and proj_dmstor but only the latter will return  */
        /* the correct end-pointer.                                     */
        if (d == dms && endp != dmsendp)
            endp = dmsendp;

        /* Break out if there were no more numerals */
        if (prev==endp)
            return i > 1? a: proj_coord_error ();

        a.v[i] = d;
        prev = endp;
        T.dimensions_given++;
    }

    return a;
}
Ejemplo n.º 3
0
static double strtod_scaled (const char *args, double default_scale) {
/*****************************************************************************
Interpret <args> as a numeric followed by a linear decadal prefix.
Return the properly scaled numeric
******************************************************************************/
    double s;
    const double GRS80_DEG = 111319.4908; /* deg-to-m at equator of GRS80 */
    const char *endp = args;
    s = proj_strtod (args, (char **) &endp);
    if (args==endp)
        return HUGE_VAL;

    endp = column (args, 2);

    if (0==strcmp(endp, "km"))
        s *= 1000;
    else if (0==strcmp(endp, "m"))
        s *= 1;
    else if (0==strcmp(endp, "dm"))
        s /= 10;
    else if (0==strcmp(endp, "cm"))
        s /= 100;
    else if (0==strcmp(endp, "mm"))
        s /= 1000;
    else if (0==strcmp(endp, "um"))
        s /= 1e6;
    else if (0==strcmp(endp, "nm"))
        s /= 1e9;
    else if (0==strcmp(endp, "rad"))
        s = GRS80_DEG * proj_todeg (s);
    else if (0==strcmp(endp, "deg"))
        s = GRS80_DEG * s;
    else
        s *= default_scale;
    return s;
}
Ejemplo n.º 4
0
static int roundtrip (const char *args) {
/*****************************************************************************
Check how far we go from the ACCEPTed point when doing successive
back/forward transformation pairs.

Without args, roundtrip defaults to 100 iterations:

  roundtrip

With one arg, roundtrip will default to a tolerance of T.tolerance:

  roundtrip ntrips

With two args:

  roundtrip ntrips tolerance

Always returns 0.
******************************************************************************/
    int ntrips;
    double d, r, ans;
    char *endp;
    PJ_COORD coo;

    if (nullptr==T.P) {
        if (T.ignore == proj_errno(T.P))
            return another_skip();

        return another_failure ();
    }

    ans = proj_strtod (args, &endp);
    if (endp==args) {
        /* Default to 100 iterations if not args. */
        ntrips = 100;
    } else {
        if (ans < 1.0 || ans > 1000000.0) {
            errmsg (2, "Invalid number of roundtrips: %lf\n", ans);
            return another_failing_roundtrip ();
        }
        ntrips = (int)ans;
    }

    d = strtod_scaled (endp, 1);
    d = d==HUGE_VAL?  T.tolerance:  d;

    /* input ("accepted") values - probably in degrees */
    coo = proj_angular_input  (T.P, T.dir)? torad_coord (T.P, T.dir, T.a):  T.a;

    r = proj_roundtrip (T.P, T.dir, ntrips, &coo);
    if (r <= d)
        return another_succeeding_roundtrip ();

    if (T.verbosity > -1) {
        if (0==T.op_ko && T.verbosity < 2)
            banner (T.operation);
        fprintf (T.fout, "%s", T.op_ko? "     -----\n": delim);
        fprintf (T.fout, "     FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) F->lineno);
        fprintf (T.fout, "     roundtrip deviation: %.6f mm, expected: %.6f mm\n", 1000*r, 1000*d);
    }
    return another_failing_roundtrip ();
}