diff options
| -rw-r--r-- | src/iso19111/factory.cpp | 29 | ||||
| -rw-r--r-- | test/unit/test_factory.cpp | 8 |
2 files changed, 29 insertions, 8 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index e7017ca3..a4529c9f 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -52,6 +52,7 @@ #include <cstring> #include <iomanip> #include <limits> +#include <locale> #include <map> #include <memory> #include <sstream> // std::ostringstream @@ -138,7 +139,8 @@ struct DatabaseContext::Private { void setPjCtxt(PJ_CONTEXT *ctxt) { pjCtxt_ = ctxt; } SQLResultSet run(const std::string &sql, - const ListOfParams ¶meters = ListOfParams()); + const ListOfParams ¶meters = ListOfParams(), + bool useMaxFloatPrecision = false); std::vector<std::string> getDatabaseStructure(); @@ -733,7 +735,8 @@ void DatabaseContext::Private::registerFunctions() { // --------------------------------------------------------------------------- SQLResultSet DatabaseContext::Private::run(const std::string &sql, - const ListOfParams ¶meters) { + const ListOfParams ¶meters, + bool useMaxFloatPrecision) { sqlite3_stmt *stmt = nullptr; auto iter = mapSqlToStatement_.find(sql); @@ -791,10 +794,20 @@ SQLResultSet DatabaseContext::Private::run(const std::string &sql, if (ret == SQLITE_ROW) { SQLRow row(column_count); for (int i = 0; i < column_count; i++) { - const char *txt = reinterpret_cast<const char *>( - sqlite3_column_text(stmt, i)); - if (txt) { - row[i] = txt; + if (useMaxFloatPrecision && + sqlite3_column_type(stmt, i) == SQLITE_FLOAT) { + // sqlite3_column_text() does not use maximum precision + std::ostringstream buffer; + buffer.imbue(std::locale::classic()); + buffer << std::setprecision(18); + buffer << sqlite3_column_double(stmt, i); + row[i] = buffer.str(); + } else { + const char *txt = reinterpret_cast<const char *>( + sqlite3_column_text(stmt, i)); + if (txt) { + row[i] = txt; + } } } result.emplace_back(std::move(row)); @@ -1646,10 +1659,10 @@ AuthorityFactory::createUnitOfMeasure(const std::string &code) const { return NN_NO_CHECK(uom); } } - auto res = d->runWithCodeParam( + auto res = d->context()->d->run( "SELECT name, conv_factor, type, deprecated FROM unit_of_measure WHERE " "auth_name = ? AND code = ?", - code); + {d->authority(), code}, true); if (res.empty()) { throw NoSuchAuthorityCodeException("unit of measure not found", d->authority(), code); diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 4f6f2c93..c7ae458e 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -95,6 +95,14 @@ TEST(factory, AuthorityFactory_createUnitOfMeasure_linear) { // --------------------------------------------------------------------------- +TEST(factory, AuthorityFactory_createUnitOfMeasure_linear_us_survey_foot) { + auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto uom = factory->createUnitOfMeasure("9003"); + EXPECT_EQ(uom->conversionToSI(), 12. / 39.37); +} + +// --------------------------------------------------------------------------- + TEST(factory, AuthorityFactory_createUnitOfMeasure_angular) { auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); auto uom = factory->createUnitOfMeasure("9102"); |
