Skip to content

Commit

Permalink
Merge pull request #4183 from rouault/decrease_exceptions
Browse files Browse the repository at this point in the history
Limit number of C++ exceptions thrown & caught internally
  • Loading branch information
rouault authored Jul 1, 2024
2 parents 88a4c89 + beaa121 commit ef281eb
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 74 deletions.
4 changes: 2 additions & 2 deletions include/proj/coordinateoperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1704,8 +1704,8 @@ class PROJ_GCC_DLL Transformation : public SingleOperation {
PROJ_INTERNAL const std::string &
getPROJ4NadgridsCompatibleFilename() const;

PROJ_FOR_TEST std::vector<double>
getTOWGS84Parameters() const; // throw(io::FormattingException)
PROJ_FOR_TEST std::vector<double> getTOWGS84Parameters(
bool canThrowException) const; // throw(io::FormattingException)

PROJ_INTERNAL const std::string &getHeightToGeographic3DFilename() const;

Expand Down
8 changes: 4 additions & 4 deletions include/proj/coordinatesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ class AxisDirection : public util::CodeList {
valueOf(const std::string &nameIn) noexcept;
//! @endcond

AxisDirection(const AxisDirection&) = delete;
AxisDirection& operator=(const AxisDirection&) = delete;
AxisDirection(AxisDirection&&) = delete;
AxisDirection& operator=(AxisDirection&&) = delete;
AxisDirection(const AxisDirection &) = delete;
AxisDirection &operator=(const AxisDirection &) = delete;
AxisDirection(AxisDirection &&) = delete;
AxisDirection &operator=(AxisDirection &&) = delete;

PROJ_DLL static const AxisDirection NORTH;
PROJ_DLL static const AxisDirection NORTH_NORTH_EAST;
Expand Down
2 changes: 1 addition & 1 deletion scripts/reference_exported_symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ osgeo::proj::operation::Transformation::createTimeDependentPositionVector(osgeo:
osgeo::proj::operation::Transformation::createTOWGS84(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, std::vector<double, std::allocator<double> > const&)
osgeo::proj::operation::Transformation::createVERTCON(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, std::string const&, std::vector<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> >, std::allocator<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> > > > const&)
osgeo::proj::operation::Transformation::createVerticalOffset(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, osgeo::proj::common::Length const&, std::vector<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> >, std::allocator<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> > > > const&)
osgeo::proj::operation::Transformation::getTOWGS84Parameters() const
osgeo::proj::operation::Transformation::getTOWGS84Parameters(bool) const
osgeo::proj::operation::Transformation::inverse() const
osgeo::proj::operation::Transformation::sourceCRS() const
osgeo::proj::operation::Transformation::targetCRS() const
Expand Down
87 changes: 51 additions & 36 deletions src/iso19111/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,41 +194,53 @@ getDBcontextNoException(PJ_CONTEXT *ctx, const char *function) {
PJ *pj_obj_create(PJ_CONTEXT *ctx, const BaseObjectNNPtr &objIn) {
auto coordop = dynamic_cast<const CoordinateOperation *>(objIn.get());
if (coordop) {
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
auto formatter = PROJStringFormatter::create(
PROJStringFormatter::Convention::PROJ_5, std::move(dbContext));
auto projString = coordop->exportToPROJString(formatter.get());
if (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;
if (pj) {
pj->iso_obj = objIn;
pj->iso_obj_is_coordinate_operation = true;
auto sourceEpoch = coordop->sourceCoordinateEpoch();
auto targetEpoch = coordop->targetCoordinateEpoch();
if (sourceEpoch.has_value()) {
if (!targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
sourceEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
} else {
if (targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
targetEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
auto singleOp = dynamic_cast<const SingleOperation *>(coordop);
bool bTryToExportToProj = true;
if (singleOp && singleOp->method()->nameStr() == "unnamed") {
// Can happen for example when the GDAL GeoTIFF SRS builder
// creates a dummy conversion when building the SRS, before setting
// the final map projection. This avoids exportToPROJString() from
// throwing an exception.
bTryToExportToProj = false;
}
if (bTryToExportToProj) {
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
auto formatter = PROJStringFormatter::create(
PROJStringFormatter::Convention::PROJ_5,
std::move(dbContext));
auto projString = coordop->exportToPROJString(formatter.get());
if (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;
if (pj) {
pj->iso_obj = objIn;
pj->iso_obj_is_coordinate_operation = true;
auto sourceEpoch = coordop->sourceCoordinateEpoch();
auto targetEpoch = coordop->targetCoordinateEpoch();
if (sourceEpoch.has_value()) {
if (!targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
sourceEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
} else {
if (targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
targetEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
}
return pj;
}
return pj;
} catch (const std::exception &) {
// Silence, since we may not always be able to export as a
// PROJ string.
}
} catch (const std::exception &) {
// Silence, since we may not always be able to export as a
// PROJ string.
}
}
auto pj = pj_new();
Expand Down Expand Up @@ -7749,16 +7761,19 @@ int proj_coordoperation_get_towgs84_values(PJ_CONTEXT *ctx,
}
return FALSE;
}
try {
auto values = transf->getTOWGS84Parameters();

const auto values = transf->getTOWGS84Parameters(false);
if (!values.empty()) {
for (int i = 0;
i < value_count && static_cast<size_t>(i) < values.size(); i++) {
out_values[i] = values[i];
}
return TRUE;
} catch (const std::exception &e) {
} else {
if (emit_error_if_incompatible) {
proj_log_error(ctx, __FUNCTION__, e.what());
proj_log_error(ctx, __FUNCTION__,
"Transformation cannot be formatted as WKT1 TOWGS84 "
"parameters");
}
return FALSE;
}
Expand Down
21 changes: 9 additions & 12 deletions src/iso19111/crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,11 +696,10 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(

const auto takeIntoAccountCandidate =
[&](const operation::TransformationNNPtr &transf) {
try {
transf->getTOWGS84Parameters();
} catch (const std::exception &) {
if (transf->getTOWGS84Parameters(false).empty()) {
return;
}

candidateCount++;
if (candidateBoundCRS == nullptr) {
candidateCount = 1;
Expand Down Expand Up @@ -1426,13 +1425,12 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
auto base3DCRS = boundCRS->baseCRS()->promoteTo3D(
newName, dbContext, verticalAxisIfNotAlreadyPresent);
auto transf = boundCRS->transformation();
try {
transf->getTOWGS84Parameters();
if (!transf->getTOWGS84Parameters(false).empty()) {
return BoundCRS::create(
createProperties(), base3DCRS,
boundCRS->hubCRS()->promoteTo3D(std::string(), dbContext),
transf->promoteTo3D(std::string(), dbContext));
} catch (const io::FormattingException &) {
} else {
return BoundCRS::create(base3DCRS, boundCRS->hubCRS(),
std::move(transf));
}
Expand Down Expand Up @@ -1481,13 +1479,12 @@ CRSNNPtr CRS::demoteTo2D(const std::string &newName,
else if (auto boundCRS = dynamic_cast<const BoundCRS *>(this)) {
auto base2DCRS = boundCRS->baseCRS()->demoteTo2D(newName, dbContext);
auto transf = boundCRS->transformation();
try {
transf->getTOWGS84Parameters();
if (!transf->getTOWGS84Parameters(false).empty()) {
return BoundCRS::create(
base2DCRS,
boundCRS->hubCRS()->demoteTo2D(std::string(), dbContext),
transf->demoteTo2D(std::string(), dbContext));
} catch (const io::FormattingException &) {
} else {
return BoundCRS::create(base2DCRS, boundCRS->hubCRS(), transf);
}
}
Expand Down Expand Up @@ -5985,7 +5982,7 @@ void BoundCRS::_exportToWKT(io::WKTFormatter *formatter) const {
io::FormattingException::Throw(
"Cannot export BoundCRS with non-WGS 84 hub CRS in WKT1");
}
auto params = d->transformation()->getTOWGS84Parameters();
auto params = d->transformation()->getTOWGS84Parameters(true);
if (!formatter->useESRIDialect()) {
formatter->setTOWGS84Parameters(params);
}
Expand Down Expand Up @@ -6075,7 +6072,7 @@ void BoundCRS::_exportToPROJString(
formatter->setHDatumExtension(std::string());
} else {
if (isTOWGS84Compatible()) {
auto params = transformation()->getTOWGS84Parameters();
auto params = transformation()->getTOWGS84Parameters(true);
formatter->setTOWGS84Parameters(params);
}
crs_exportable->_exportToPROJString(formatter);
Expand Down Expand Up @@ -6137,7 +6134,7 @@ BoundCRS::_identify(const io::AuthorityFactoryPtr &authorityFactory) const {
}
bool refIsNullTransform = false;
if (isTOWGS84Compatible()) {
auto params = transformation()->getTOWGS84Parameters();
auto params = transformation()->getTOWGS84Parameters(true);
if (params == std::vector<double>{0, 0, 0, 0, 0, 0, 0}) {
refIsNullTransform = true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/iso19111/operation/singleoperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,8 +1443,8 @@ bool SingleOperation::_isEquivalentTo(const util::IComparable *other,
isTOWGS84Transf(otherMethodEPSGCode)) {
auto transf = static_cast<const Transformation *>(this);
auto otherTransf = static_cast<const Transformation *>(otherSO);
auto params = transf->getTOWGS84Parameters();
auto otherParams = otherTransf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto otherParams = otherTransf->getTOWGS84Parameters(true);
assert(params.size() == 7);
assert(otherParams.size() == 7);
for (size_t i = 0; i < 7; i++) {
Expand Down
10 changes: 8 additions & 2 deletions src/iso19111/operation/transformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,14 @@ Transformation::demoteTo2D(const std::string &,
* can be used as the value of the WKT1 TOWGS84 parameter or
* PROJ +towgs84 parameter.
*
* @param canThrowException if true, an exception is thrown if the method fails,
* otherwise an empty vector is returned in case of failure.
* @return a vector of 7 values if valid, otherwise a io::FormattingException
* is thrown.
* @throws io::FormattingException
*/
std::vector<double>
Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
std::vector<double> Transformation::getTOWGS84Parameters(
bool canThrowException) const // throw(io::FormattingException)
{
// GDAL WKT1 assumes EPSG:9606 / Position Vector convention

Expand Down Expand Up @@ -297,6 +299,8 @@ Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
(foundRotX && foundRotY && foundRotZ && foundScale))) {
return params;
} else {
if (!canThrowException)
return {};
throw io::FormattingException(
"Missing required parameter values in transformation");
}
Expand All @@ -321,6 +325,8 @@ Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
}
#endif

if (!canThrowException)
return {};
throw io::FormattingException(
"Transformation cannot be formatted as WKT1 TOWGS84 parameters");
}
Expand Down
2 changes: 1 addition & 1 deletion src/projections/imoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static double compute_zone_x_boundary(PJ *P, double lam, double phi) {
lp2.phi = phi;
xy1 = imoll_s_forward(lp1, P);
xy2 = imoll_s_forward(lp2, P);
return (xy1.x + xy2.x)/2.;
return (xy1.x + xy2.x) / 2.;
}

PJ *PJ_PROJECTION(imoll) {
Expand Down
6 changes: 3 additions & 3 deletions src/projections/imoll_o.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ pj_imoll_o_compute_zone_offset(struct pj_imoll_o_ns::pj_imoll_o_data *Q,
return (xy2.x + Q->pj[zone2 - 1]->x0) - (xy1.x + Q->pj[zone1 - 1]->x0);
}

static double
pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam, double phi) {
static double pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam,
double phi) {
PJ_LP lp1, lp2;
PJ_XY xy1, xy2;

Expand All @@ -248,7 +248,7 @@ pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam, double phi) {
lp2.phi = phi;
xy1 = imoll_o_s_forward(lp1, P);
xy2 = imoll_o_s_forward(lp2, P);
return (xy1.x + xy2.x)/2.;
return (xy1.x + xy2.x) / 2.;
}

PJ *PJ_PROJECTION(imoll_o) {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/gie_self_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ TEST_F(gieTest, proj_create_crs_to_crs) {

TEST_F(gieTest, proj_create_crs_to_crs_EPSG_4326) {

auto P =
proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4326", "EPSG:32631", nullptr);
auto P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4326", "EPSG:32631",
nullptr);
ASSERT_TRUE(P != nullptr);
PJ_COORD a, b;

Expand Down
10 changes: 5 additions & 5 deletions test/unit/test_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5033,7 +5033,7 @@ TEST(wkt_parse, BOUNDCRS_transformation_from_names) {
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(),
projcrs->baseCRS()->nameStr());

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5082,7 +5082,7 @@ TEST(wkt_parse, BOUNDCRS_transformation_from_codes) {
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(),
projcrs->baseCRS()->nameStr());

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5224,7 +5224,7 @@ TEST(wkt_parse, geogcs_TOWGS84_3terms) {
ASSERT_TRUE(crs->transformation()->sourceCRS() != nullptr);
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(), "my GEOGCRS");

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5270,7 +5270,7 @@ TEST(wkt_parse, projcs_TOWGS84_7terms) {
ASSERT_TRUE(crs->transformation()->sourceCRS() != nullptr);
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(), "my GEOGCRS");

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5313,7 +5313,7 @@ TEST(io, projcs_TOWGS84_7terms_autocorrect) {
auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj);
ASSERT_TRUE(crs != nullptr);

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{-106.8686, 52.2978, -103.7239, 0.3366,
-0.457, 1.8422, -1.2747};
ASSERT_EQ(params.size(), expected.size());
Expand Down
8 changes: 4 additions & 4 deletions test/unit/test_operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ TEST(operation, transformation_createGeocentricTranslations) {
2.0, 3.0, std::vector<PositionalAccuracyNNPtr>());
EXPECT_TRUE(transf->validateParameters().empty());

auto params = transf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0};
EXPECT_EQ(params, expected);

Expand All @@ -570,7 +570,7 @@ TEST(operation, transformation_createGeocentricTranslations) {
inv_transf_as_transf->sourceCRS()->nameStr());
auto expected_inv =
std::vector<double>{-1.0, -2.0, -3.0, 0.0, 0.0, 0.0, 0.0};
EXPECT_EQ(inv_transf_as_transf->getTOWGS84Parameters(), expected_inv);
EXPECT_EQ(inv_transf_as_transf->getTOWGS84Parameters(true), expected_inv);

EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
Expand Down Expand Up @@ -677,7 +677,7 @@ TEST(operation, transformation_createPositionVector) {
ASSERT_EQ(transf->coordinateOperationAccuracies().size(), 1U);

auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
EXPECT_EQ(transf->getTOWGS84Parameters(), expected);
EXPECT_EQ(transf->getTOWGS84Parameters(true), expected);

EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
Expand Down Expand Up @@ -744,7 +744,7 @@ TEST(operation, transformation_createCoordinateFrameRotation) {
std::vector<PositionalAccuracyNNPtr>());
EXPECT_TRUE(transf->validateParameters().empty());

auto params = transf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
EXPECT_EQ(params, expected);

Expand Down

0 comments on commit ef281eb

Please sign in to comment.