Пример #1
0
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 */
}
Пример #2
0
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;
}