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; }
/* file processing function --- verbosely */ static void vprocess(FILE *fid) { char line[MAX_LINE+3], *s, pline[40]; PJ_LP dat_ll; PJ_XY dat_xy; int linvers; PJ_COORD coord; if (!oform) oform = "%.3f"; if (bin_in || bin_out) emess(1,"binary I/O not available in -V option"); for (;;) { proj_errno_reset(Proj); ++emess_dat.File_line; if (!(s = fgets(line, MAX_LINE, fid))) break; if (!strchr(s, '\n')) { /* overlong line */ int c; (void)strcat(s, "\n"); /* gobble up to newline */ while ((c = fgetc(fid)) != EOF && c != '\n') ; } if (*s == tag) { /* pass on data */ (void)fputs(s, stdout); continue; } /* check to override default input mode */ if (*s == 'I' || *s == 'i') { linvers = 1; ++s; } else linvers = inverse; if (linvers) { if (!PJ_INVERS(Proj)) { emess(-1,"inverse for this projection not avail.\n"); continue; } dat_xy.x = strtod(s, &s); dat_xy.y = strtod(s, &s); if (dat_xy.x == HUGE_VAL || dat_xy.y == HUGE_VAL) { emess(-1,"lon-lat input conversion failure\n"); continue; } if (prescale) { dat_xy.x *= fscale; dat_xy.y *= fscale; } if (reversein) { PJ_XY temp = dat_xy; dat_xy.x = temp.y; dat_xy.y = temp.x; } dat_ll = pj_inv(dat_xy, Proj); } else { dat_ll.lam = proj_dmstor(s, &s); dat_ll.phi = proj_dmstor(s, &s); if (dat_ll.lam == HUGE_VAL || dat_ll.phi == HUGE_VAL) { emess(-1,"lon-lat input conversion failure\n"); continue; } if (reversein) { PJ_LP temp = dat_ll; dat_ll.lam = temp.phi; dat_ll.phi = temp.lam; } dat_xy = pj_fwd(dat_ll, Proj); if (postscale) { dat_xy.x *= fscale; dat_xy.y *= fscale; } } /* For some reason pj_errno does not work as expected in some */ /* versions of Visual Studio, so using pj_get_errno_ref instead */ if (*pj_get_errno_ref()) { emess(-1, pj_strerrno(*pj_get_errno_ref())); continue; } if (!*s && (s > line)) --s; /* assumed we gobbled \n */ coord.lp = dat_ll; facs = proj_factors(Proj, coord); if (proj_errno(Proj)) { emess(-1,"failed to compute factors\n\n"); continue; } if (*s != '\n') (void)fputs(s, stdout); (void)fputs("Longitude: ", stdout); (void)fputs(proj_rtodms(pline, dat_ll.lam, 'E', 'W'), stdout); (void)printf(" [ %.11g ]\n", dat_ll.lam * RAD_TO_DEG); (void)fputs("Latitude: ", stdout); (void)fputs(proj_rtodms(pline, dat_ll.phi, 'N', 'S'), stdout); (void)printf(" [ %.11g ]\n", dat_ll.phi * RAD_TO_DEG); (void)fputs("Easting (x): ", stdout); (void)printf(oform, dat_xy.x); putchar('\n'); (void)fputs("Northing (y): ", stdout); (void)printf(oform, dat_xy.y); putchar('\n'); (void)printf("Meridian scale (h) : %.8f ( %.4g %% error )\n", facs.meridional_scale, (facs.meridional_scale-1.)*100.); (void)printf("Parallel scale (k) : %.8f ( %.4g %% error )\n", facs.parallel_scale, (facs.parallel_scale-1.)*100.); (void)printf("Areal scale (s): %.8f ( %.4g %% error )\n", facs.areal_scale, (facs.areal_scale-1.)*100.); (void)printf("Angular distortion (w): %.3f\n", facs.angular_distortion * RAD_TO_DEG); (void)printf("Meridian/Parallel angle: %.5f\n", facs.meridian_parallel_angle * RAD_TO_DEG); (void)printf("Convergence : "); (void)fputs(proj_rtodms(pline, facs.meridian_convergence, 0, 0), stdout); (void)printf(" [ %.8f ]\n", facs.meridian_convergence * RAD_TO_DEG); (void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", facs.tissot_semimajor, facs.tissot_semiminor); } }
PROJ_PVALUE /* test for presence or get parameter value */ proj_param(paralist *pl, const char *opt) { int type; unsigned l; PROJ_PVALUE value; type = *opt++; /* simple linear lookup */ l = (unsigned)strlen(opt); while (pl && !(!strncmp(pl->param, opt, l) && (!pl->param[l] || pl->param[l] == '='))) pl = pl->next; if (type == 't') value.i = pl != 0; else if (pl) { pl->used |= 1; opt = pl->param + l; if (*opt == '=') ++opt; switch (type) { case 'i': /* integer input */ value.i = atoi(opt); break; case 'd': /* simple real input */ value.f = atof(opt); break; case 'r': /* degrees input */ value.f = proj_dmstor(opt, 0); break; case 's': /* char string */ value.s = opt; break; case 'b': /* boolean */ switch (*opt) { case 'F': case 'f': value.i = 0; break; case '\0': case 'T': case 't': value.i = 1; break; default: proj_errno = -8; value.i = 0; break; } break; default: bum_type: /* note: this is an error in parameter, not a user error */ fprintf(stderr, "invalid request to proj_param, fatal\n"); exit(1); } } else /* not given */ switch (type) { case 'b': case 'i': value.i = 0; break; case 'd': case 'r': value.f = 0.; break; case 's': value.s = 0; break; default: goto bum_type; } return value; }