aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/iso19111/factory.cpp29
-rw-r--r--test/unit/test_factory.cpp8
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 &parameters = ListOfParams());
+ const ListOfParams &parameters = 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 &parameters) {
+ const ListOfParams &parameters,
+ 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");