Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail consistently on network error and grid transformations #4302

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/iso19111/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,13 @@ PJ *pj_obj_create(PJ_CONTEXT *ctx, const BaseObjectNNPtr &objIn) {
PROJStringFormatter::Convention::PROJ_5,
std::move(dbContext));
auto projString = coordop->exportToPROJString(formatter.get());
if (proj_context_is_network_enabled(ctx)) {
const bool defer_grid_opening_backup = ctx->defer_grid_opening;
if (!defer_grid_opening_backup &&
proj_context_is_network_enabled(ctx)) {
ctx->defer_grid_opening = true;
}
auto pj = pj_create_internal(ctx, projString.c_str());
ctx->defer_grid_opening = false;
ctx->defer_grid_opening = defer_grid_opening_backup;
if (pj) {
pj->iso_obj = objIn;
pj->iso_obj_is_coordinate_operation = true;
Expand Down
9 changes: 7 additions & 2 deletions src/transformations/gridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct GridInfo {
struct gridshiftData {
ListOfGenericGrids m_grids{};
bool m_defer_grid_opening = false;
int m_error_code_in_defer_grid_opening = 0;
bool m_bHasHorizontalOffset = false;
bool m_bHasGeographic3DOffset = false;
bool m_bHasEllipsoidalHeightOffset = false;
Expand Down Expand Up @@ -724,10 +725,14 @@ PJ_XYZ gridshiftData::grid_apply_internal(
// ---------------------------------------------------------------------------

bool gridshiftData::loadGridsIfNeeded(PJ *P) {
if (m_defer_grid_opening) {
if (m_error_code_in_defer_grid_opening) {
proj_errno_set(P, m_error_code_in_defer_grid_opening);
return false;
} else if (m_defer_grid_opening) {
m_defer_grid_opening = false;
m_grids = pj_generic_grid_init(P, "grids");
if (proj_errno(P)) {
m_error_code_in_defer_grid_opening = proj_errno(P);
if (m_error_code_in_defer_grid_opening) {
return false;
}
bool isProjectedCoord;
Expand Down
17 changes: 11 additions & 6 deletions src/transformations/hgridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct hgridshiftData {
double t_epoch = 0;
ListOfHGrids grids{};
bool defer_grid_opening = false;
int error_code_in_defer_grid_opening = 0;
};
} // anonymous namespace

Expand All @@ -33,9 +34,11 @@ static PJ_XYZ pj_hgridshift_forward_3d(PJ_LPZ lpz, PJ *P) {
if (Q->defer_grid_opening) {
Q->defer_grid_opening = false;
Q->grids = pj_hgrid_init(P, "grids");
if (proj_errno(P)) {
return proj_coord_error().xyz;
}
Q->error_code_in_defer_grid_opening = proj_errno(P);
}
if (Q->error_code_in_defer_grid_opening) {
proj_errno_set(P, Q->error_code_in_defer_grid_opening);
return proj_coord_error().xyz;
}

if (!Q->grids.empty()) {
Expand All @@ -55,9 +58,11 @@ static PJ_LPZ pj_hgridshift_reverse_3d(PJ_XYZ xyz, PJ *P) {
if (Q->defer_grid_opening) {
Q->defer_grid_opening = false;
Q->grids = pj_hgrid_init(P, "grids");
if (proj_errno(P)) {
return proj_coord_error().lpz;
}
Q->error_code_in_defer_grid_opening = proj_errno(P);
}
if (Q->error_code_in_defer_grid_opening) {
proj_errno_set(P, Q->error_code_in_defer_grid_opening);
return proj_coord_error().lpz;
}

if (!Q->grids.empty()) {
Expand Down
17 changes: 11 additions & 6 deletions src/transformations/vgridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct vgridshiftData {
double forward_multiplier = 0;
ListOfVGrids grids{};
bool defer_grid_opening = false;
int error_code_in_defer_grid_opening = 0;
};
} // anonymous namespace

Expand Down Expand Up @@ -60,9 +61,11 @@ static PJ_XYZ pj_vgridshift_forward_3d(PJ_LPZ lpz, PJ *P) {
Q->defer_grid_opening = false;
Q->grids = pj_vgrid_init(P, "grids");
deal_with_vertcon_gtx_hack(P);
if (proj_errno(P)) {
return proj_coord_error().xyz;
}
Q->error_code_in_defer_grid_opening = proj_errno(P);
}
if (Q->error_code_in_defer_grid_opening) {
proj_errno_set(P, Q->error_code_in_defer_grid_opening);
return proj_coord_error().xyz;
}

if (!Q->grids.empty()) {
Expand All @@ -84,9 +87,11 @@ static PJ_LPZ pj_vgridshift_reverse_3d(PJ_XYZ xyz, PJ *P) {
Q->defer_grid_opening = false;
Q->grids = pj_vgrid_init(P, "grids");
deal_with_vertcon_gtx_hack(P);
if (proj_errno(P)) {
return proj_coord_error().lpz;
}
Q->error_code_in_defer_grid_opening = proj_errno(P);
}
if (Q->error_code_in_defer_grid_opening) {
proj_errno_set(P, Q->error_code_in_defer_grid_opening);
return proj_coord_error().lpz;
}

if (!Q->grids.empty()) {
Expand Down
9 changes: 6 additions & 3 deletions src/transformations/xyzgridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct xyzgridshiftData {
bool grid_ref_is_input = true;
ListOfGenericGrids grids{};
bool defer_grid_opening = false;
int error_code_in_defer_grid_opening = 0;
double multiplier = 1.0;
};
} // anonymous namespace
Expand All @@ -56,9 +57,11 @@ static bool get_grid_values(PJ *P, xyzgridshiftData *Q, const PJ_LP &lp,
if (Q->defer_grid_opening) {
Q->defer_grid_opening = false;
Q->grids = pj_generic_grid_init(P, "grids");
if (proj_errno(P)) {
return false;
}
Q->error_code_in_defer_grid_opening = proj_errno(P);
}
if (Q->error_code_in_defer_grid_opening) {
proj_errno_set(P, Q->error_code_in_defer_grid_opening);
return false;
}

GenericShiftGridSet *gridset = nullptr;
Expand Down
229 changes: 222 additions & 7 deletions test/unit/test_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,26 +1234,241 @@ TEST(networking, network_endpoint_env_variable) {

#ifdef CURL_ENABLED

TEST(networking, network_endpoint_api) {
TEST(networking, network_endpoint_api_and_not_reachable_gridshift) {
auto ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
proj_context_set_enable_network(ctx, true);
proj_context_set_url_endpoint(ctx, "http://0.0.0.0");

// NAD83 to NAD83(HARN) in West-Virginia. Using wvhpgn.tif
// NAD83 to NAD83(HARN) using
// us_noaa_nadcon5_nad83_1986_nad83_harn_conus.tif
auto P = proj_create_crs_to_crs(ctx, "EPSG:4269", "EPSG:4152", nullptr);
ASSERT_NE(P, nullptr);

PJ_COORD c;
c.xyz.x = 40; // lat
c.xyz.y = -80; // long
c.xyz.z = 0;
c = proj_trans(P, PJ_FWD, c);
c.xyzt.x = 40; // lat
c.xyzt.y = -80; // long
c.xyzt.z = 0;
c.xyzt.t = HUGE_VAL;

{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"NAD83 to NAD83(HARN) (47)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check again. Cf https://github.com/pyproj4/pyproj/issues/705
{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"NAD83 to NAD83(HARN) (47)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check also reverse direction
{
PJ_COORD c2 = proj_trans(P, PJ_INV, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"NAD83 to NAD83(HARN) (47)");
proj_destroy(last_op);
}

proj_destroy(P);
proj_context_destroy(ctx);
}

EXPECT_EQ(c.xyz.x, HUGE_VAL);
#endif

// ---------------------------------------------------------------------------

#ifdef CURL_ENABLED

TEST(networking, network_endpoint_api_and_not_reachable_xyzgridshift) {
auto ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
proj_context_set_enable_network(ctx, true);
proj_context_set_url_endpoint(ctx, "http://0.0.0.0");

// NTF to RGF93 using fr_ign_gr3df97a.tif
auto P = proj_create_crs_to_crs(ctx, "EPSG:4275", "EPSG:4171", nullptr);
ASSERT_NE(P, nullptr);

PJ_COORD c;
c.xyzt.x = 49; // lat
c.xyzt.y = 2; // long
c.xyzt.z = 0;
c.xyzt.t = HUGE_VAL;

{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "NTF to RGF93 v1 (1)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check again. Cf https://github.com/pyproj4/pyproj/issues/705
{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "NTF to RGF93 v1 (1)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check also reverse direction
{
PJ_COORD c2 = proj_trans(P, PJ_INV, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "NTF to RGF93 v1 (1)");
proj_destroy(last_op);
}

proj_destroy(P);
proj_context_destroy(ctx);
}

#endif

// ---------------------------------------------------------------------------

#ifdef CURL_ENABLED

TEST(networking, network_endpoint_api_and_not_reachable_hgridshift) {
auto ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
proj_context_set_enable_network(ctx, true);
proj_context_set_url_endpoint(ctx, "http://0.0.0.0");

// MGI to ETRS89 using at_bev_AT_GIS_GRID_2021_09_28.tif
auto P = proj_create_crs_to_crs(ctx, "EPSG:4312", "EPSG:4258", nullptr);
ASSERT_NE(P, nullptr);

PJ_COORD c;
c.xyzt.x = 48; // lat
c.xyzt.y = 15; // long
c.xyzt.z = 0;
c.xyzt.t = HUGE_VAL;

{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "MGI to ETRS89 (8)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check again. Cf https://github.com/pyproj4/pyproj/issues/705
{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "MGI to ETRS89 (8)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check also reverse direction
{
PJ_COORD c2 = proj_trans(P, PJ_INV, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description, "MGI to ETRS89 (8)");
proj_destroy(last_op);
}

proj_destroy(P);
proj_context_destroy(ctx);
}

#endif

// ---------------------------------------------------------------------------

#ifdef CURL_ENABLED

TEST(networking, network_endpoint_api_and_not_reachable_vgridshift) {
auto ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
proj_context_set_enable_network(ctx, true);
proj_context_set_url_endpoint(ctx, "http://0.0.0.0");

// "POSGAR 2007 to SRVN16 height (1)" using ar_ign_GEOIDE-Ar16.tif
auto P = proj_create_crs_to_crs(ctx, "EPSG:5342", "EPSG:9521", nullptr);
ASSERT_NE(P, nullptr);

PJ_COORD c;
c.xyzt.x = -40; // lat
c.xyzt.y = -60; // long
c.xyzt.z = 0;
c.xyzt.t = HUGE_VAL;

{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"POSGAR 2007 to SRVN16 height (1)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check again. Cf https://github.com/pyproj4/pyproj/issues/705
{
PJ_COORD c2 = proj_trans(P, PJ_FWD, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"POSGAR 2007 to SRVN16 height (1)");
proj_destroy(last_op);
}

proj_errno_reset(P);

// Check also reverse direction
{
PJ_COORD c2 = proj_trans(P, PJ_INV, c);
EXPECT_EQ(c2.xyz.x, HUGE_VAL);
EXPECT_EQ(proj_errno(P), PROJ_ERR_OTHER_NETWORK_ERROR);
PJ *last_op = proj_trans_get_last_used_operation(P);
EXPECT_STREQ(proj_pj_info(last_op).description,
"POSGAR 2007 to SRVN16 height (1)");
proj_destroy(last_op);
}

proj_destroy(P);
proj_context_destroy(ctx);
}

#endif
Expand Down
Loading