#2018 CSV import. Fix decimal point/locale

This commit is contained in:
Bjørn Erik Jensen 2017-11-24 09:57:03 +01:00
parent 11100fb6e0
commit 28db4c6e22
7 changed files with 36 additions and 27 deletions

View File

@ -32,15 +32,17 @@ std::string RiaStdStringTools::trimString(const std::string& s)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RiaStdStringTools::isNumber(const std::string& s) bool RiaStdStringTools::isNumber(const std::string& s, char decimalPoint)
{ {
if (s.size() == 0) return false; if (s.size() == 0) return false;
if (findCharMatchCount(s, '.') > 1) return false; if (findCharMatchCount(s, decimalPoint) > 1) return false;
if (findCharMatchCount(s, '-') > 1) return false; if (findCharMatchCount(s, '-') > 1) return false;
if (findCharMatchCount(s, 'e') > 1) return false; if (findCharMatchCount(s, 'e') > 1) return false;
if (findCharMatchCount(s, 'E') > 1) return false; if (findCharMatchCount(s, 'E') > 1) return false;
return (s.find_first_not_of("0123456789.eE-") == std::string::npos); std::string matchChars("0123456789eE-");
matchChars.append(1, decimalPoint);
return (s.find_first_not_of(matchChars) == std::string::npos);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ class RiaStdStringTools
{ {
public: public:
static std::string trimString(const std::string& s); static std::string trimString(const std::string& s);
static bool isNumber(const std::string& s); static bool isNumber(const std::string& s, char decimalPoint);
static int toInt(const std::string& s); static int toInt(const std::string& s);
static double toDouble(const std::string& s); static double toDouble(const std::string& s);

View File

@ -162,7 +162,7 @@ std::vector<RimAsciiDataCurve*> RicPasteAsciiDataToSummaryPlotFeature::parseCurv
{ {
std::vector<RimAsciiDataCurve*> curves; std::vector<RimAsciiDataCurve*> curves;
const AsciiDataParseOptions& parseOptions = settings.parseOptions(); const AsciiDataParseOptions& parseOptions = settings.parseOptions();
RifColumnBasedAsciiParser parser = RifColumnBasedAsciiParser(data, parseOptions.dateTimeFormat(), parseOptions.decimalSeparator, parseOptions.cellSeparator); RifColumnBasedAsciiParser parser = RifColumnBasedAsciiParser(data, parseOptions.dateTimeFormat(), parseOptions.locale, parseOptions.cellSeparator);
if (parser.headers().empty()) if (parser.headers().empty())
{ {

View File

@ -148,18 +148,22 @@ const AsciiDataParseOptions RicPasteAsciiDataToSummaryPlotFeatureUi::parseOption
{ {
QString separator; QString separator;
QLocale locale;
switch (m_decimalSeparator()) switch (m_decimalSeparator())
{ {
case DECIMAL_COMMA: case DECIMAL_COMMA:
separator = ","; separator = ",";
locale = QLocale::Norwegian;
break; break;
case DECIMAL_DOT: case DECIMAL_DOT:
default: default:
separator = "."; separator = ".";
locale = QLocale::c();
break; break;
} }
parseOptions.decimalSeparator = separator; parseOptions.decimalSeparator = separator;
parseOptions.locale = locale;
} }
{ {

View File

@ -36,6 +36,7 @@ public:
QString plotTitle; QString plotTitle;
QString curvePrefix; QString curvePrefix;
QString decimalSeparator; QString decimalSeparator;
QLocale locale;
QString dateFormat; QString dateFormat;
QString timeFormat; QString timeFormat;
QString cellSeparator; QString cellSeparator;

View File

@ -59,8 +59,7 @@ bool RifCsvUserData::parse(const QString& fileName, const AsciiDataParseOptions&
m_mapFromAddressToResultIndex.clear(); m_mapFromAddressToResultIndex.clear();
m_parser = std::unique_ptr<RifCsvUserDataFileParser>(new RifCsvUserDataFileParser(fileName, errorText)); m_parser = std::unique_ptr<RifCsvUserDataFileParser>(new RifCsvUserDataFileParser(fileName, errorText));
m_parser->parse(parseOptions); if (!m_parser->parse(parseOptions))
if (!m_parser)
{ {
RiaLogging::error(QString("Failed to parse file")); RiaLogging::error(QString("Failed to parse file"));
return false; return false;

View File

@ -168,9 +168,14 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions)
for (int iCol = 0; iCol < colCount; iCol++) for (int iCol = 0; iCol < colCount; iCol++)
{ {
std::string colName = columnNames[iCol].toStdString(); QString colName = columnNames[iCol];
RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::importedAddress(colName); RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::importedAddress(colName.toStdString());
ColumnInfo col = ColumnInfo::createColumnInfoFromCsvData(addr, ""); ColumnInfo col = ColumnInfo::createColumnInfoFromCsvData(addr, "");
if (colName == parseOptions.timeSeriesColumnName)
{
col.dataType = ColumnInfo::DATETIME;
}
cols.push_back(col); cols.push_back(col);
} }
} }
@ -180,7 +185,7 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions)
return false; return false;
} }
while (!dataStream->atEnd()) while (!dataStream->atEnd() && !errors)
{ {
QString line = dataStream->readLine(); QString line = dataStream->readLine();
if(line.trimmed().isEmpty()) continue; if(line.trimmed().isEmpty()) continue;
@ -200,21 +205,19 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions)
std::string colData = lineColumns[iCol].toStdString(); std::string colData = lineColumns[iCol].toStdString();
ColumnInfo& col = cols[iCol]; ColumnInfo& col = cols[iCol];
// Check if text column // Determine column data type
if (RiaStdStringTools::isNumber(colData)) if (col.dataType == ColumnInfo::NONE)
{
if (RiaStdStringTools::isNumber(colData, parseOptions.locale.decimalPoint().toAscii()))
{ {
col.dataType = ColumnInfo::NUMERIC; col.dataType = ColumnInfo::NUMERIC;
} }
else if (tryParseDateTime(colData, parseOptions.dateTimeFormat()).isValid() ||
tryParseDateTime(colData, parseOptions.dateFormat).isValid())
{
col.dataType = ColumnInfo::DATETIME;
}
else else
{ {
col.dataType = ColumnInfo::TEXT; col.dataType = ColumnInfo::TEXT;
} }
} }
}
parseState = DATA_ROW; parseState = DATA_ROW;
} }
@ -223,25 +226,25 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions)
{ {
for (int iCol = 0; iCol < colCount; iCol++) for (int iCol = 0; iCol < colCount; iCol++)
{ {
std::string colData = lineColumns[iCol].toStdString(); QString& colData = lineColumns[iCol];
ColumnInfo& col = cols[iCol]; ColumnInfo& col = cols[iCol];
try try
{ {
if (col.dataType == ColumnInfo::NUMERIC) if (col.dataType == ColumnInfo::NUMERIC)
{ {
col.values.push_back(RiaStdStringTools::toDouble(colData)); col.values.push_back(parseOptions.locale.toDouble(colData));
} }
else if (col.dataType == ColumnInfo::TEXT) else if (col.dataType == ColumnInfo::TEXT)
{ {
col.textValues.push_back(colData); col.textValues.push_back(colData.toStdString());
} }
else if (col.dataType == ColumnInfo::DATETIME) else if (col.dataType == ColumnInfo::DATETIME)
{ {
QDateTime dt = tryParseDateTime(colData, parseOptions.dateTimeFormat()); QDateTime dt = tryParseDateTime(colData.toStdString(), parseOptions.dateTimeFormat());
if (!dt.isValid()) if (!dt.isValid())
{ {
dt = tryParseDateTime(colData, parseOptions.dateFormat); dt = tryParseDateTime(colData.toStdString(), parseOptions.dateFormat);
} }
if (!dt.isValid()) throw 0; if (!dt.isValid()) throw 0;
col.dateTimeValues.push_back(dt); col.dateTimeValues.push_back(dt);