aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-03-04 00:32:01 +0100
committerGitHub <noreply@github.com>2020-03-04 00:32:01 +0100
commit04f74f53962de4149aa32c35c13148268fd37cd2 (patch)
treead15dc198f435482957c3a8ad39fcdf0c50f709c /src
parente8fbfa59a982ff5f8f29c320c4bd66eb461d8b2c (diff)
parent0fce24abcb18bbbad0821331fd970908e74bc22a (diff)
downloadPROJ-04f74f53962de4149aa32c35c13148268fd37cd2.tar.gz
PROJ-04f74f53962de4149aa32c35c13148268fd37cd2.zip
Merge pull request #2013 from PROJ-BOT/backport-2011-to-6.3
[Backport 6.3] createUnitOfMeasure(): use full double resolution for the conversion factor
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/factory.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 2fe12fb3..e3bbcf95 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -50,6 +50,7 @@
#include <cstring>
#include <iomanip>
#include <limits>
+#include <locale>
#include <map>
#include <memory>
#include <sstream> // std::ostringstream
@@ -136,7 +137,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();
@@ -827,7 +829,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);
@@ -885,10 +888,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));
@@ -1705,10 +1718,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);