Skip to content

Commit

Permalink
Add option in proj CLI to use a CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
jjimenezshaw committed Jul 16, 2023
1 parent f440bfd commit b1707bd
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
12 changes: 10 additions & 2 deletions docs/source/apps/proj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ invproj

Synopsis
********
**proj** [**-beEfiIlmorsStTvVwW**] [args]] [*+opt[=arg]* ...] file ...
**proj** [**-beEfiIlmorsStTvVwWC**] [args]] [*+opt[=arg]* ...] file ...

**invproj** [**-beEfiIlmorsStTvVwW**] [args]] [*+opt[=arg]* ...] file ...
**invproj** [**-beEfiIlmorsStTvVwWC**] [args]] [*+opt[=arg]* ...] file ...


Description
Expand Down Expand Up @@ -157,6 +157,14 @@ The following control parameters can appear in any order
This option causes an expanded annotated listing of the characteristics of
the projected point. :option:`-v` is implied with this option.

.. option:: -C <crs>

.. versionadded:: 9.3.0

Where *crs* is a definition of a Projected CRS, as its WKT or code
for instance EPSG:32632. This option generates the projection to
the underlying geographic system. When used, it ignores *+opt* arguments.


The *+opt* run-line arguments are associated with cartographic parameters.
Additional projection control parameters may be contained in two auxiliary
Expand Down
45 changes: 44 additions & 1 deletion src/apps/proj.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* <<<< Cartographic projection filter program >>>> */
#include "proj.h"
#include "emess.h"
#include "proj_experimental.h"
#include "proj_internal.h"
#include "utils.h"
#include <ctype.h>
Expand Down Expand Up @@ -48,6 +49,8 @@ static const char *oterr = "*\t*", /* output line for unprojectable input */
*usage = "%s\nusage: %s [-bdeEfiIlmorsStTvVwW [args]] [+opt[=arg] ...] "
"[file ...]\n";

static const char *ocrs = nullptr; /* CRS use case */

static PJ_FACTORS facs;

static double (*informat)(const char *,
Expand Down Expand Up @@ -496,6 +499,11 @@ int main(int argc, char **argv) {
case 's': /* reverse output */
reverseout = 1;
continue;
case 'C': /* CRS use case */
if (--argc <= 0)
goto noargument;
ocrs = *++argv;
continue;
default:
emess(1, "invalid option: -%c", *arg);
break;
Expand Down Expand Up @@ -525,11 +533,46 @@ int main(int argc, char **argv) {
}
proj_context_use_proj4_init_rules(nullptr, true);

if (ocrs) {
// logic copied from proj_factors function
if (PJ *P = proj_create(nullptr, ocrs)) {
const auto type = proj_get_type(P);
if (type == PJ_TYPE_PROJECTED_CRS) {
auto ctx = P->ctx;
auto geodetic_crs = proj_get_source_crs(ctx, P);
assert(geodetic_crs);
auto datum = proj_crs_get_datum(ctx, geodetic_crs);
auto datum_ensemble =
proj_crs_get_datum_ensemble(ctx, geodetic_crs);
auto cs = proj_create_ellipsoidal_2D_cs(
ctx, PJ_ELLPS2D_LONGITUDE_LATITUDE, "Radian", 1.0);
auto temp = proj_create_geographic_crs_from_datum(
ctx, "unnamed crs", datum ? datum : datum_ensemble, cs);
proj_destroy(datum);
proj_destroy(datum_ensemble);
proj_destroy(cs);
proj_destroy(geodetic_crs);
Proj = proj_create_crs_to_crs_from_pj(ctx, temp, P, nullptr,
nullptr);
proj_destroy(temp);
} else {
emess(3, "CRS must be projected");
}
proj_destroy(P);
} else {
emess(3, "-C argument is not parseable");
}
if (!argvVector.empty()) {
emess(-1, "+opt arguments are ignored due to -C option");
}
}

// proj historically ignores any datum shift specifier, like nadgrids,
// towgs84, etc
argvVector.push_back(const_cast<char *>("break_cs2cs_recursion"));

if (!(Proj = proj_create_argv(nullptr, static_cast<int>(argvVector.size()),
if (!Proj &&
!(Proj = proj_create_argv(nullptr, static_cast<int>(argvVector.size()),
argvVector.data())))
emess(3, "projection initialization failure\ncause: %s",
proj_errno_string(proj_context_errno(nullptr)));
Expand Down

0 comments on commit b1707bd

Please sign in to comment.