Skip to content

Commit

Permalink
proj_create_crs_to_crs(): emit a warning if the best transformation c…
Browse files Browse the repository at this point in the history
…annot be used / cs2cs: add a --only-best=no switch
  • Loading branch information
rouault committed Jan 2, 2023
1 parent 5ada02c commit 8fda5c1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 16 deletions.
9 changes: 5 additions & 4 deletions docs/source/apps/cs2cs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Synopsis
| **cs2cs** [**-eEfIlrstvwW** [args]]
| [[--area <name_or_code>] | [--bbox <west_long,south_lat,east_long,north_lat>]]
| [--authority <name>] [--3d]
| [--accuracy <accuracy>] [--only-best] [--no-ballpark]
| [--accuracy <accuracy>] [--only-best[=yes|=no]] [--no-ballpark]
| ([*+opt[=arg]* ...] [+to *+opt[=arg]* ...] | {source_crs} {target_crs})
| file ...
Expand Down Expand Up @@ -167,12 +167,13 @@ The following control parameters can appear in any order:
`south_lat` and `north_lat` in the [-90,90]. `west_long` is generally lower than
`east_long`, except in the case where the area of interest crosses the antimeridian.

.. option:: --only-best
.. option:: --only-best[=yes|=no]

.. versionadded:: 9.2.0

Error out if the best transformation, known of PROJ, and usable by PROJ if
all grids known and usable by PROJ were accessible, cannot be used.
If set to yes, error out if the best transformation, known of PROJ, and
usable by PROJ if all grids known and usable by PROJ were accessible,
cannot be used.
Best transformation should be understood as the transformation returned by
:cpp:func:`proj_get_suggested_operation` if all known grids were
accessible (either locally or through network).
Expand Down
40 changes: 32 additions & 8 deletions src/4D_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ similarly, but prefers the 2D resp. 3D interfaces if available.
if( res.xyzt.x != HUGE_VAL ) {
return res;
}
else if( P->errorIfBestTransformationNotAvailable ) {
else if( P->errorIfBestTransformationNotAvailable ||
P->ctx->warnIfBestTransformationNotAvailable ) {
std::string msg("Attempt to use coordinate operation ");
msg += alt.name;
msg += " failed.";
Expand All @@ -367,8 +368,18 @@ similarly, but prefers the 2D resp. 3D interfaces if available.
msg += " is not available.";
}
}
pj_log(P->ctx, PJ_LOG_ERROR, msg.c_str());
return res;
if( P->ctx->warnIfBestTransformationNotAvailable )
{
msg += " This will become an error in PROJ 10. "
"Set the ONLY_BEST option to YES or NO. "
"This warning will no longer be emitted (for the current context).";
P->ctx->warnIfBestTransformationNotAvailable = false;
}
pj_log(P->ctx,
P->errorIfBestTransformationNotAvailable ? PJ_LOG_ERROR : PJ_LOG_WARNING,
msg.c_str());
if( P->errorIfBestTransformationNotAvailable )
return res;
}
if( iRetry == N_MAX_RETRY ) {
break;
Expand Down Expand Up @@ -1939,6 +1950,7 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
return nullptr;
}
} else if ((value = getOptionValue(*iter, "ONLY_BEST="))) {
ctx->warnIfBestTransformationNotAvailable = false;
if( ci_equal(value, "yes") )
errorIfBestTransformationNotAvailable = true;
else if( ci_equal(value, "no") )
Expand Down Expand Up @@ -1996,7 +2008,9 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
ctx, operation_ctx, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
proj_operation_factory_context_set_grid_availability_use(
ctx, operation_ctx,
(errorIfBestTransformationNotAvailable || proj_context_is_network_enabled(ctx)) ?
(errorIfBestTransformationNotAvailable ||
ctx->warnIfBestTransformationNotAvailable ||
proj_context_is_network_enabled(ctx)) ?
PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE:
PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID);

Expand All @@ -2018,7 +2032,7 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
ctx->forceOver = forceOver;

const int old_debug_level = ctx->debug_level;
if( errorIfBestTransformationNotAvailable )
if( errorIfBestTransformationNotAvailable || ctx->warnIfBestTransformationNotAvailable )
ctx->debug_level = PJ_LOG_NONE;
PJ* P = proj_list_get(ctx, op_list, 0);
ctx->debug_level = old_debug_level;
Expand All @@ -2031,7 +2045,8 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
ctx->forceOver = false;

if( P != nullptr &&
errorIfBestTransformationNotAvailable &&
(errorIfBestTransformationNotAvailable ||
ctx->warnIfBestTransformationNotAvailable) &&
!proj_coordoperation_is_instantiable(ctx, P) )
{
std::string msg("Attempt to use coordinate operation ");
Expand All @@ -2052,13 +2067,22 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons
msg += " is not available.";
}
}
pj_log(ctx, PJ_LOG_ERROR, msg.c_str());
if( ctx->warnIfBestTransformationNotAvailable )
{
msg += " This will become an error in PROJ 10. "
"Set the ONLY_BEST option to YES or NO. "
"This warning will no longer be emitted (for the current context).";
ctx->warnIfBestTransformationNotAvailable = false;
}
pj_log(ctx,
errorIfBestTransformationNotAvailable ? PJ_LOG_ERROR : PJ_LOG_WARNING,
msg.c_str());
}

return P;
}

if( errorIfBestTransformationNotAvailable )
if( errorIfBestTransformationNotAvailable || ctx->warnIfBestTransformationNotAvailable )
ctx->debug_level = PJ_LOG_NONE;
auto preparedOpList = pj_create_prepared_operations(ctx, source_crs, target_crs,
op_list);
Expand Down
20 changes: 16 additions & 4 deletions src/apps/cs2cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static const char *usage =
"%s\nusage: %s [-dDeEfIlrstvwW [args]]\n"
" [[--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]]\n"
" [--authority {name}] [--3d]\n"
" [--accuracy {accuracy}] [--only-best] [--no-ballpark]\n"
" [--accuracy {accuracy}] [--only-best[=yes|=no]] [--no-ballpark]\n"
" [+opt[=arg] ...] [+to +opt[=arg] ...] [file ...]\n";

static double (*informat)(const char *,
Expand Down Expand Up @@ -419,6 +419,7 @@ int main(int argc, char **argv) {
const char* authority = nullptr;
double accuracy = -1;
bool allowBallpark = true;
bool onlyBestSet = false;
bool errorIfBestTransformationNotAvailable = false;
bool promoteTo3D = false;

Expand Down Expand Up @@ -486,9 +487,15 @@ int main(int argc, char **argv) {
else if (strcmp(*argv, "--no-ballpark") == 0 ) {
allowBallpark = false;
}
else if (strcmp(*argv, "--only-best") == 0 ) {
else if (strcmp(*argv, "--only-best") == 0 ||
strcmp(*argv, "--only-best=yes") == 0 ) {
onlyBestSet = true;
errorIfBestTransformationNotAvailable = true;
}
else if (strcmp(*argv, "--only-best=no") == 0 ) {
onlyBestSet = true;
errorIfBestTransformationNotAvailable = false;
}
else if (strcmp(*argv, "--3d") == 0 ) {
promoteTo3D = true;
}
Expand Down Expand Up @@ -898,8 +905,13 @@ int main(int argc, char **argv) {
if( !allowBallpark ) {
options.push_back("ALLOW_BALLPARK=NO");
}
if( errorIfBestTransformationNotAvailable ) {
options.push_back("ONLY_BEST=YES");
if( onlyBestSet ) {
if( errorIfBestTransformationNotAvailable ) {
options.push_back("ONLY_BEST=YES");
}
else {
options.push_back("ONLY_BEST=NO");
}
}
options.push_back(nullptr);
transformation = proj_create_crs_to_crs_from_pj(nullptr, src, dst,
Expand Down
1 change: 1 addition & 0 deletions src/ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ pj_ctx::pj_ctx(const pj_ctx& other) :
lastFullErrorMessage(std::string()),
last_errno(0),
debug_level(other.debug_level),
warnIfBestTransformationNotAvailable(other.warnIfBestTransformationNotAvailable),
logger(other.logger),
logger_app_data(other.logger_app_data),
cpp_context(other.cpp_context ? other.cpp_context->clone(this) : nullptr),
Expand Down
1 change: 1 addition & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ struct pj_ctx{
std::string lastFullErrorMessage{}; // used by proj_context_errno_string
int last_errno = 0;
int debug_level = PJ_LOG_WARNING;
bool warnIfBestTransformationNotAvailable = true; /* to remove in PROJ 10 */
void (*logger)(void *, int, const char *) = nullptr;
void *logger_app_data = nullptr;
struct projCppContext* cpp_context = nullptr; /* internal context for C++ code */
Expand Down
21 changes: 21 additions & 0 deletions test/cli/testvarious
Original file line number Diff line number Diff line change
Expand Up @@ -1089,13 +1089,34 @@ $EXE --only-best NTF RGF93 -E >>${OUT} 2>&1 <<EOF
49 2 0
EOF

echo "##############################################################" >> ${OUT}
echo "Test cs2cs (grid missing)" >> ${OUT}
#
$EXE EPSG:4326+3855 EPSG:4979 -E >>${OUT} 2>&1 <<EOF
49 2 0
EOF

echo "##############################################################" >> ${OUT}
echo "Test cs2cs --only-best=no (grid missing)" >> ${OUT}
#
$EXE --only-best=no EPSG:4326+3855 EPSG:4979 -E >>${OUT} 2>&1 <<EOF
49 2 0
EOF

echo "##############################################################" >> ${OUT}
echo "Test cs2cs --only-best (grid missing)" >> ${OUT}
#
$EXE --only-best EPSG:4326+3855 EPSG:4979 -E >>${OUT} 2>&1 <<EOF
49 2 0
EOF

echo "##############################################################" >> ${OUT}
echo "Test cs2cs --only-best=yes (grid missing)" >> ${OUT}
#
$EXE --only-best=yes EPSG:4326+3855 EPSG:4979 -E >>${OUT} 2>&1 <<EOF
49 2 0
EOF

echo "##############################################################" >> ${OUT}
echo "Test cs2cs --only-best (grid missing)" >> ${OUT}
#
Expand Down
11 changes: 11 additions & 0 deletions test/cli/tv_out.dist
Original file line number Diff line number Diff line change
Expand Up @@ -532,10 +532,21 @@ program abnormally terminated
Test cs2cs --only-best (working)
49 2 0 48d59'59.756"N 1d59'57.4"E 0.000
##############################################################
Test cs2cs (grid missing)
Warning: Attempt to use coordinate operation Inverse of WGS 84 to EGM2008 height (1) failed. Grid us_nga_egm08_25.tif is not available. This will become an error in PROJ 10. Set the ONLY_BEST option to YES or NO. This warning will no longer be emitted (for the current context).
49 2 0 49dN 2dE 0.000
##############################################################
Test cs2cs --only-best=no (grid missing)
49 2 0 49dN 2dE 0.000
##############################################################
Test cs2cs --only-best (grid missing)
Attempt to use coordinate operation Inverse of WGS 84 to EGM2008 height (1) failed. Grid us_nga_egm08_25.tif is not available.
49 2 0 * * inf
##############################################################
Test cs2cs --only-best=yes (grid missing)
Attempt to use coordinate operation Inverse of WGS 84 to EGM2008 height (1) failed. Grid us_nga_egm08_25.tif is not available.
49 2 0 * * inf
##############################################################
Test cs2cs --only-best (grid missing)
Attempt to use coordinate operation NAD27 to NAD83 (7) failed. Grid us_noaa_nadcon5_nad27_nad83_1986_conus.tif is not available.
40 -100 0 * * inf
Expand Down

0 comments on commit 8fda5c1

Please sign in to comment.