diff --git a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp b/src/lib/marble/geodata/data/GeoDataCoordinates.cpp --- a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp +++ b/src/lib/marble/geodata/data/GeoDataCoordinates.cpp @@ -42,6 +42,12 @@ private: enum DirPosition { PrefixDir, PostfixDir }; + /** + * Parses the double value from the input string in system locale + * if it contains the system locale decimalpoint char, + * otherwise parses it in the C locale. + */ + static double parseDouble(const QString& input); static QString createDecimalPointExp(); static QString regExp( const QString& string ); static void getLocaleList( QStringList& localeList, const QString& localeListString, @@ -255,8 +261,8 @@ const QRegExp regex = QRegExp( numberCapExp ); if( regex.exactMatch(input) ) { - m_lon = regex.cap(2).toDouble(); - m_lat = regex.cap(1).toDouble(); + m_lon = parseDouble(regex.cap(2)); + m_lat = parseDouble(regex.cap(1)); return true; } @@ -427,6 +433,16 @@ return true; } +double LonLatParser::parseDouble(const QString& input) +{ + // Decide by decimalpoint if system locale or C locale should be tried. + // Otherwise if first trying with a system locale when the string is in C locale, + // the "." might be misinterpreted as thousands group separator and thus a wrong + // value yielded + QLocale locale = QLocale::system(); + return input.contains(locale.decimalPoint()) ? locale.toDouble(input) : input.toDouble(); +} + QString LonLatParser::createDecimalPointExp() { const QChar decimalPoint = QLocale::system().decimalPoint(); @@ -521,7 +537,7 @@ const bool isNegativeValue = (regex.cap( c++ ) == QLatin1String("-")); const uint degree = regex.cap( c++ ).toUInt(); const uint minutes = regex.cap( c++ ).toUInt(); - const qreal seconds = regex.cap( c ).toDouble(); + const qreal seconds = parseDouble(regex.cap( c )); qreal result = degree + (minutes*MIN2HOUR) + (seconds*SEC2HOUR); @@ -537,7 +553,7 @@ { const bool isNegativeValue = (regex.cap( c++ ) == QLatin1String("-")); const uint degree = regex.cap( c++ ).toUInt(); - const qreal minutes = regex.cap( c ).toDouble(); + const qreal minutes = parseDouble(regex.cap( c )); qreal result = degree + (minutes*MIN2HOUR); @@ -551,7 +567,7 @@ qreal LonLatParser::degreeValueFromD( const QRegExp& regex, int c, bool isPosHemisphere ) { - qreal result = regex.cap( c ).toDouble(); + qreal result = parseDouble(regex.cap( c )); if (! isPosHemisphere) result *= -1; diff --git a/tests/TestGeoDataCoordinates.cpp b/tests/TestGeoDataCoordinates.cpp --- a/tests/TestGeoDataCoordinates.cpp +++ b/tests/TestGeoDataCoordinates.cpp @@ -515,6 +515,7 @@ enum SphereType {PosSphere, NegSphere}; enum UnitsType {NoUnits, WithUnits}; enum SpacesType {NoSpaces, WithSpaces}; +enum LocaleType {CLocale, SystemLocale}; //static QString //createDegreeString(SignType signType, @@ -565,13 +566,18 @@ static QString createDegreeString(SignType signType, qreal degreeValue, + LocaleType locale, UnitsType unitsType, SpacesType spacesType) { QString string; // add degree if (signType != NoSign) string.append(QLatin1Char(signType==PositiveSign?'+':'-')); - string.append(QString::fromLatin1("%L1").arg(degreeValue, 0, 'f', 10)); + if (locale == CLocale) { + string.append(QString::number(degreeValue, 'f', 10)); + } else { + string.append(QLocale::system().toString(degreeValue, 'f', 10)); + } if (unitsType == WithUnits) string.append(QChar(0xb0)); if (spacesType == WithSpaces) string.append(QLatin1Char(' ')); @@ -839,6 +845,8 @@ << NoUnits << WithUnits; const QVector spacesTypes = QVector() << NoSpaces << WithSpaces; + const QVector localeTypes = QVector() + << CLocale << SystemLocale; const QVector degreeSamples = QVector() << qreal(0.0) << qreal(3.14159) << qreal(180.0); @@ -859,6 +867,8 @@ (latSphere==PosSphere && latSignType!=NegativeSign) || (latSphere==NegSphere && latSignType==NegativeSign); foreach(const qreal latDegree, degreeSamples) { + // locale + foreach(const LocaleType locale, localeTypes) { // actual construction // Create lon & lat values @@ -873,11 +883,13 @@ QString string; string.append(createDegreeString(latSignType, latDegree, + locale, unitsType, spacesType)); string.append(QLatin1Char(latSphere==PosSphere?'N':'S')); string.append(QLatin1Char(' ')); string.append(createDegreeString(lonSignType, lonDegree, + locale, unitsType, spacesType)); string.append(QLatin1Char(lonSphere==PosSphere?'E':'W')); @@ -887,12 +899,13 @@ .append(QLatin1String(unitsType==WithUnits?"|units":"|no units")) .append(QLatin1String("|lon:")) .append(QLatin1Char(lonIsPositive?'+':'-')) - .append(QString::fromLatin1("%L1").arg(lonDegree, 0, 'f', 10)+QChar(0xb0)) + .append(QString::number(lonDegree, 'f', 10)+QChar(0xb0)) .append(QLatin1Char(lonSphere==PosSphere?'P':'N')) .append(QLatin1String("|lat:")) .append(QLatin1Char(latIsPositive?'+':'-')) - .append(QString::fromLatin1("%L1").arg(latDegree, 0, 'f', 10)+QChar(0xb0)) + .append(QString::number(latDegree, 'f', 10)+QChar(0xb0)) .append(QLatin1Char(latSphere==PosSphere?'P':'N')) + .append(QLatin1Char('|')).append(QLatin1Char(locale==CLocale?'C':'L')) .append(QLatin1Char('|')).append(string).append(QLatin1Char('|')); QTest::newRow(rowTitle.toLatin1()) << string @@ -906,6 +919,7 @@ } } } + } QTest::newRow("scientific notation") << "0.0,1.0e-2" << qreal(1.0e-2) << qreal(0.0); QTest::newRow("scientific notation") << "-2.4E0 1.0e-18" << qreal(1e-18) << qreal(-2.4e0);