int main(int argc, char **argv) { char *arg, **eargv = argv, *from_argv[MAX_PARGS], *to_argv[MAX_PARGS], **iargv = argv; FILE *fid; int from_argc = 0, to_argc = 0, iargc = argc, eargc = 0, c, mon = 0; int have_to_flag = 0, inverse = 0, i; if ((emess_dat.Prog_name = strrchr(*argv, DIR_CHAR)) != NULL) ++emess_dat.Prog_name; else emess_dat.Prog_name = *argv; inverse = !strncmp(emess_dat.Prog_name, "inv", 3); if (argc <= 1) { (void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name); exit(0); } /* process run line arguments */ while (--argc > 0) { /* collect run line arguments */ if (**++argv == '-') for (arg = *argv;;) { switch (*++arg) { case '\0': /* position of "stdin" */ if (arg[-1] == '-') eargv[eargc++] = "-"; break; case 'v': /* monitor dump of initialization */ mon = 1; continue; case 'I': /* alt. method to spec inverse */ inverse = 1; continue; case 'E': /* echo ascii input to ascii output */ echoin = 1; continue; case 't': /* set col. one char */ if (arg[1]) tag = *++arg; else emess(1, "missing -t col. 1 tag"); continue; case 'l': /* list projections, ellipses or units */ if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') { /* list projections */ struct PJ_LIST *lp; int do_long = arg[1] == 'P', c; char *str; for (lp = pj_get_list_ref(); lp->id; ++lp) { (void)printf("%s : ", lp->id); if (do_long) /* possibly multiline description */ (void)puts(*lp->descr); else { /* first line, only */ str = *lp->descr; while ((c = *str++) && c != '\n') putchar(c); putchar('\n'); } } } else if (arg[1] == '=') { /* list projection 'descr' */ struct PJ_LIST *lp; arg += 2; for (lp = pj_get_list_ref(); lp->id; ++lp) if (!strcmp(lp->id, arg)) { (void)printf("%9s : %s\n", lp->id, *lp->descr); break; } } else if (arg[1] == 'e') { /* list ellipses */ struct PJ_ELLPS *le; for (le = pj_get_ellps_ref(); le->id; ++le) (void)printf("%9s %-16s %-16s %s\n", le->id, le->major, le->ell, le->name); } else if (arg[1] == 'u') { /* list units */ struct PJ_UNITS *lu; for (lu = pj_get_units_ref(); lu->id; ++lu) (void)printf("%12s %-20s %s\n", lu->id, lu->to_meter, lu->name); } else if (arg[1] == 'd') { /* list datums */ struct PJ_DATUMS *ld; printf("__datum_id__ __ellipse___ __definition/comments______________________________\n"); for (ld = pj_get_datums_ref(); ld->id; ++ld) { printf("%12s %-12s %-30s\n", ld->id, ld->ellipse_id, ld->defn); if (ld->comments != NULL && strlen(ld->comments) > 0) printf("%25s %s\n", " ", ld->comments); } } else if (arg[1] == 'm') { /* list prime meridians */ struct PJ_PRIME_MERIDIANS *lpm; for (lpm = pj_get_prime_meridians_ref(); lpm->id; ++lpm) (void)printf("%12s %-30s\n", lpm->id, lpm->defn); } else emess(1, "invalid list option: l%c", arg[1]); exit(0); continue; /* artificial */ case 'e': /* error line alternative */ if (--argc <= 0) noargument: emess(1, "missing argument for -%c", *arg); oterr = *++argv; continue; case 'W': /* specify seconds precision */ case 'w': /* -W for constant field width */ if ((c = arg[1]) != 0 && isdigit(c)) { set_rtodms(c - '0', *arg == 'W'); ++arg; } else emess(1, "-W argument missing or non-digit"); continue; case 'f': /* alternate output format degrees or xy */ if (--argc <= 0) goto noargument; oform = *++argv; continue; case 'r': /* reverse input */ reversein = 1; continue; case 's': /* reverse output */ reverseout = 1; continue; case 'd': /* set debug level */ if (--argc <= 0) goto noargument; pj_ctx_set_debug(pj_get_default_ctx(), atoi(*++argv)); continue; default: emess(1, "invalid option: -%c", *arg); break; } break; } else if (strcmp(*argv, "+to") == 0) { have_to_flag = 1; } else if (**argv == '+') { /* + argument */ if (have_to_flag) { if (to_argc < MAX_PARGS) to_argv[to_argc++] = *argv + 1; else emess(1, "overflowed + argument table"); } else { if (from_argc < MAX_PARGS) from_argv[from_argc++] = *argv + 1; else emess(1, "overflowed + argument table"); } } else /* assumed to be input file name(s) */ eargv[eargc++] = *argv; } if (eargc == 0) /* if no specific files force sysin */ eargv[eargc++] = "-"; /* * If the user has requested inverse, then just reverse the * coordinate systems. */ if (inverse) { int argcount; for (i = 0; i < MAX_PARGS; i++) { char *arg; arg = from_argv[i]; from_argv[i] = to_argv[i]; to_argv[i] = arg; } argcount = from_argc; from_argc = to_argc; to_argc = argcount; } if (!(fromProj = pj_init(from_argc, from_argv))) { printf("Using from definition: "); for (i = 0; i < from_argc; i++) printf("%s ", from_argv[i]); printf("\n"); emess(3, "projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } if (to_argc == 0) { if (!(toProj = pj_latlong_from_proj(fromProj))) { printf("Using to definition: "); for (i = 0; i < to_argc; i++) printf("%s ", to_argv[i]); printf("\n"); emess(3, "projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } } else if (!(toProj = pj_init(to_argc, to_argv))) { printf("Using to definition: "); for (i = 0; i < to_argc; i++) printf("%s ", to_argv[i]); printf("\n"); emess(3, "projection initialization failure\ncause: %s", pj_strerrno(pj_errno)); } if (mon) { printf("%c ---- From Coordinate System ----\n", tag); pj_pr_list(fromProj); printf("%c ---- To Coordinate System ----\n", tag); pj_pr_list(toProj); } /* set input formating control */ if (!fromProj->is_latlong) informat = strtod; else { informat = dmstor; } if (!toProj->is_latlong && !oform) oform = "%.2f"; /* process input file list */ for (; eargc--; ++eargv) { if (**eargv == '-') { fid = stdin; emess_dat.File_name = "<stdin>"; } else { if ((fid = fopen(*eargv, "rt")) == NULL) { emess(-2, *eargv, "input file"); continue; } emess_dat.File_name = *eargv; } emess_dat.File_line = 0; process(fid); fclose(fid); emess_dat.File_name = 0; } if (fromProj != NULL) pj_free(fromProj); if (toProj != NULL) pj_free(toProj); pj_deallocate_grids(); exit(0); /* normal completion */ }
static CPLString GetProj4Filename(const char* pszFilename) { CPLString osFilename; /* or fixed path: /name, ./name or ../name */ if ( !CPLIsFilenameRelative(pszFilename) || *pszFilename == '.' ) { return pszFilename; } #if defined(PROJ_STATIC) && PROJ_VERSION >= 5 PJ_GRID_INFO info = proj_grid_info(pszFilename); if( info.filename[0] ) { osFilename = info.filename; } #elif defined(PROJ_STATIC) && PJ_VERSION > 493 osFilename.resize(2048); projCtx ctx = pj_ctx_alloc(); if( pj_find_file(ctx, pszFilename, &osFilename[0], osFilename.size()) ) { osFilename.resize( strlen(osFilename) ); } else { osFilename.clear(); } pj_ctx_free(ctx); #else // Transpose some of the proj.4 pj_open_lib() logic... /* check if ~/name */ char* pszSysname; if (*pszFilename == '~' && (pszFilename[1] == '/' || pszFilename[1] == '\\') ) { if ((pszSysname = getenv("HOME")) != nullptr) { osFilename = CPLFormFilename(pszSysname, pszFilename + 1, nullptr); } return osFilename; } /* or is environment PROJ_LIB defined */ else if ((pszSysname = getenv("PROJ_LIB")) != nullptr) { osFilename = CPLFormFilename(pszSysname, pszFilename, nullptr); VSIStatBufL sStat; if( VSIStatL(osFilename, &sStat) == 0 ) return osFilename; osFilename.clear(); } #if defined(PROJ_STATIC) && PJ_VERSION >= 490 // Super messy. proj.4 up to 4.9.3 had no public API to return the full // path to a resource file, so we rely on the fact that it emits a log // message with it... // Basically this is needed in the case where the file is in the // resource installation directory of proj.4, which we have no way to // know otherwise. CPLString osMsg; projCtx ctx = pj_ctx_alloc(); pj_ctx_set_app_data(ctx, &osMsg); pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR); pj_ctx_set_logger(ctx, my_proj4_logger); PAFile f = pj_open_lib(ctx, pszFilename, "rb"); if( f ) { pj_ctx_fclose(ctx, f); size_t nPos = osMsg.find("fopen("); if( nPos != std::string::npos ) { osFilename = osMsg.substr(nPos + strlen("fopen(")); nPos = osFilename.find(")"); if( nPos != std::string::npos ) osFilename = osFilename.substr(0, nPos); } } pj_ctx_free(ctx); #endif #endif return osFilename; }