Skip to content

Commit

Permalink
Add proj_degree_input() and proj_degree_output()
Browse files Browse the repository at this point in the history
Equivalent to proj_angular_input() and proj_angular_output() but
checking for degree units instead. proj_create_crs_to_crs() rarely, if
ever, returns pipelines that has radians as input or output so using
proj_angular_*() is not a useful check for io units of pipelines.

These two new functions should make life a bit easier for users that
generally store there angular coordinates in radians.

Closes OSGeo#2027
  • Loading branch information
kbevers committed Apr 11, 2020
1 parent 21ebdfb commit d5a3055
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 5 deletions.
20 changes: 20 additions & 0 deletions docs/source/development/reference/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,26 @@ Various
:type `direction`: PJ_DIRECTION
:returns: :c:type:`int` 1 if output units is expected in radians, otherwise 0
.. c:function:: int proj_degree_input (PJ *P, enum PJ_DIRECTION dir)
Check if a operation expects input in degrees or not.
:param `P`: Transformation object
:type `P`: const PJ*
:param `direction`: Starting direction of transformation
:type `direction`: PJ_DIRECTION
:returns: :c:type:`int` 1 if input units is expected in degrees, otherwise 0
.. c:function:: int proj_degree_output (PJ *P, enum PJ_DIRECTION dir)
Check if an operation returns output in degrees or not.
:param `P`: Transformation object
:type `P`: const PJ*
:param `direction`: Starting direction of transformation
:type `direction`: PJ_DIRECTION
:returns: :c:type:`int` 1 if output units is expected in degrees, otherwise 0
Setting custom I/O functions
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down
21 changes: 21 additions & 0 deletions src/4D_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,27 @@ int proj_angular_output (PJ *P, enum PJ_DIRECTION dir) {
return proj_angular_input (P, opposite_direction(dir));
}

/*****************************************************************************/
int proj_degree_input (PJ *P, enum PJ_DIRECTION dir) {
/******************************************************************************
Returns 1 if the operator P expects degree input coordinates when
operating in direction dir, 0 otherwise.
dir: {PJ_FWD, PJ_INV}
******************************************************************************/
if (PJ_FWD==dir)
return pj_left (P)==PJ_IO_UNITS_DEGREES;
return pj_right (P)==PJ_IO_UNITS_DEGREES;
}

/*****************************************************************************/
int proj_degree_output (PJ *P, enum PJ_DIRECTION dir) {
/******************************************************************************
Returns 1 if the operator P provides degree output coordinates when
operating in direction dir, 0 otherwise.
dir: {PJ_FWD, PJ_INV}
******************************************************************************/
return proj_degree_input (P, opposite_direction(dir));
}

/* Geodesic distance (in meter) + fwd and rev azimuth between two points on the ellipsoid */
PJ_COORD proj_geod (const PJ *P, PJ_COORD a, PJ_COORD b) {
Expand Down
16 changes: 12 additions & 4 deletions src/conversions/unitconvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,12 @@ PJ *CONVERSION(unitconvert,0) {
return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID);
}
Q->xy_factor = f;
if (normalized_name != nullptr && strcmp(normalized_name, "Radian") == 0)
P->left = PJ_IO_UNITS_RADIANS;
if (normalized_name != nullptr) {
if (strcmp(normalized_name, "Radian") == 0)
P->left = PJ_IO_UNITS_RADIANS;
if (strcmp(normalized_name, "Degree") == 0)
P->left = PJ_IO_UNITS_DEGREES;
}
}

if ((name = pj_param (P->ctx, P->params, "sxy_out").s) != nullptr) {
Expand All @@ -491,8 +495,12 @@ PJ *CONVERSION(unitconvert,0) {
return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID);
}
Q->xy_factor /= f;
if (normalized_name != nullptr && strcmp(normalized_name, "Radian") == 0)
P->right= PJ_IO_UNITS_RADIANS;
if (normalized_name != nullptr) {
if (strcmp(normalized_name, "Radian") == 0)
P->right= PJ_IO_UNITS_RADIANS;
if (strcmp(normalized_name, "Degree") == 0)
P->right= PJ_IO_UNITS_DEGREES;
}
}

if( xy_in_is_linear >= 0 && xy_out_is_linear >= 0 &&
Expand Down
3 changes: 3 additions & 0 deletions src/fwd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ static PJ_COORD fwd_finalize (PJ *P, PJ_COORD coo) {
case PJ_IO_UNITS_WHATEVER:
break;

case PJ_IO_UNITS_DEGREES:
break;

case PJ_IO_UNITS_RADIANS:
coo.lpz.z = P->vfr_meter * (coo.lpz.z + P->z0);

Expand Down
3 changes: 3 additions & 0 deletions src/inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ static PJ_COORD inv_prepare (PJ *P, PJ_COORD coo) {
case PJ_IO_UNITS_WHATEVER:
return coo;

case PJ_IO_UNITS_DEGREES:
return coo;

/* de-scale and de-offset */
case PJ_IO_UNITS_CARTESIAN:
coo.xyz.x *= P->to_meter;
Expand Down
2 changes: 2 additions & 0 deletions src/proj.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ typedef enum PJ_DIRECTION PJ_DIRECTION;
int PROJ_DLL proj_angular_input (PJ *P, enum PJ_DIRECTION dir);
int PROJ_DLL proj_angular_output (PJ *P, enum PJ_DIRECTION dir);

int PROJ_DLL proj_degree_input (PJ *P, enum PJ_DIRECTION dir);
int PROJ_DLL proj_degree_output (PJ *P, enum PJ_DIRECTION dir);

PJ_COORD PROJ_DLL proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coord);
int PROJ_DLL proj_trans_array (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord);
Expand Down
4 changes: 3 additions & 1 deletion src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ enum pj_io_units {
PJ_IO_UNITS_CLASSIC = 1, /* Scaled meters (right), projected system */
PJ_IO_UNITS_PROJECTED = 2, /* Meters, projected system */
PJ_IO_UNITS_CARTESIAN = 3, /* Meters, 3D cartesian system */
PJ_IO_UNITS_RADIANS = 4 /* Radians */
PJ_IO_UNITS_RADIANS = 4, /* Radians */
PJ_IO_UNITS_DEGREES = 5, /* Degrees */

};
enum pj_io_units pj_left (PJ *P);
enum pj_io_units pj_right (PJ *P);
Expand Down
14 changes: 14 additions & 0 deletions test/unit/proj_angular_io_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,18 @@ TEST(AngularUnits, Pipelines3) {
proj_context_destroy(ctx);
}

TEST(DegreeUnits, Pipelines) {
auto ctx = proj_context_create();
auto P = proj_create_crs_to_crs(ctx, "EPSG:25832", "EPSG:4258", NULL);

EXPECT_FALSE(proj_degree_input(P, PJ_FWD));
EXPECT_TRUE(proj_degree_input(P, PJ_INV));
EXPECT_TRUE(proj_degree_output(P, PJ_FWD));
EXPECT_FALSE(proj_degree_output(P, PJ_INV));

proj_destroy(P);
proj_context_destroy(ctx);

}

} // namespace

0 comments on commit d5a3055

Please sign in to comment.