proj_create_crs_to_crs(): emit a debug message if the best transformation cannot be used / cs2cs: add a --only-best=no switch

This commit is contained in:
Even Rouault committed 2023-01-10 23:37:28 +01:00
1 parent fdd9901917
commit d11c9d5766
7 files changed
+90 -19

No files matched your search

+9 -7
View File
@@ -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 ...
@@ -167,15 +167,17 @@ 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.
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).
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 most accurate transformation
available among all relevant for the point to transform, and if all known
grids required to perform such transformation were accessible (either locally
or through network).
.. option:: --no-ballpark
+32 -8
View File
@@ -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.";
@@ -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 might become an error in a future PROJ major release. "
"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_DEBUG,
msg.c_str());
if( P->errorIfBestTransformationNotAvailable )
return res;
}
if( iRetry == N_MAX_RETRY ) {
break;
@@ -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") )
@@ -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);
@@ -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;
@@ -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 ");
@@ -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 might become an error in a future PROJ major release."
"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_DEBUG,
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);
+16 -4
View File
@@ -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 *,
@@ -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;
@@ -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;
}
@@ -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,
+1
View File
@@ -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),
+1
View File
@@ -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_ERROR;
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 */
+21
View File
@@ -1089,6 +1089,20 @@ $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}
#
@@ -1096,6 +1110,13 @@ $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}
#
+10
View File
@@ -532,10 +532,20 @@ 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)
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