Lat-lon parsing: accept lower case NSEW, fix precision

Thanks to Wkitty for catching both problems.
This commit is contained in:
James Turner 2018-06-28 22:43:30 +01:00
parent b1d6a41c65
commit 609ac93c10
2 changed files with 20 additions and 15 deletions

View File

@ -1140,9 +1140,9 @@ bool parseStringAsLatLonValue(const std::string& s, double& degrees)
auto spacePos = ss.find_first_of(" *");
if (spacePos == std::string::npos) {
degrees = std::stof(ss);
degrees = std::stod(ss);
} else {
degrees = std::stof(ss.substr(0, spacePos));
degrees = std::stod(ss.substr(0, spacePos));
double minutes = 0.0, seconds = 0.0;
@ -1151,13 +1151,13 @@ bool parseStringAsLatLonValue(const std::string& s, double& degrees)
if (quotePos == std::string::npos) {
const auto minutesStr = ss.substr(spacePos+1);
if (!minutesStr.empty()) {
minutes = std::stof(minutesStr);
minutes = std::stod(minutesStr);
}
} else {
minutes = std::stof(ss.substr(spacePos+1, quotePos - spacePos));
minutes = std::stod(ss.substr(spacePos+1, quotePos - spacePos));
const auto secondsStr = ss.substr(quotePos+1);
if (!secondsStr.empty()) {
seconds = std::stof(secondsStr);
seconds = std::stod(secondsStr);
}
}
@ -1171,7 +1171,7 @@ bool parseStringAsLatLonValue(const std::string& s, double& degrees)
}
// since we simplified, any trailing N/S/E/W must be the last char
const char lastChar = ss.back();
const char lastChar = ::toupper(ss.back());
if ((lastChar == 'W') || (lastChar == 'S')) {
degrees = -degrees;
}

View File

@ -625,27 +625,32 @@ void test_parseGeod()
SGGeod a;
SG_VERIFY(strutils::parseStringAsGeod("56.12,-3.0", &a));
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -3.0);
SG_CHECK_EQUAL_EP2(a.getLatitudeDeg(), 56.12, 1e-4);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), 56.12);
SG_VERIFY(strutils::parseStringAsGeod("56.12345678s,3.12345678w", &a));
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -3.12345678);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), -56.12345678);
// trailing degrees
SG_VERIFY(strutils::parseStringAsGeod("56.12*,-3.0*", &a));
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -3.0);
SG_CHECK_EQUAL_EP2(a.getLatitudeDeg(), 56.12, 1e-4);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), 56.12);
// embedded whitepace, DMS notation, NSEW notation
SG_VERIFY(strutils::parseStringAsGeod("\t40 30'50\"S, 12 34'56\"W ", &a));
SG_CHECK_EQUAL_EP2(a.getLongitudeDeg(), -12.58222222, 1e-4);
SG_CHECK_EQUAL_EP2(a.getLatitudeDeg(), -40.5138888, 1e-4);
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -12.58222222);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), -40.5138888);
// embedded whitepace, DMS notation, NSEW notation, degrees symbol
SG_VERIFY(strutils::parseStringAsGeod("\t40*30'50\"S, 12*34'56\"W ", &a));
SG_CHECK_EQUAL_EP2(a.getLongitudeDeg(), -12.58222222, 1e-4);
SG_CHECK_EQUAL_EP2(a.getLatitudeDeg(), -40.5138888, 1e-4);
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -12.58222222);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), -40.5138888);
// signed degrees-minutes
SG_VERIFY(strutils::parseStringAsGeod("-45 27.89,-12 34.56", &a));
SG_CHECK_EQUAL_EP2(a.getLongitudeDeg(), -12.576, 1e-4);
SG_CHECK_EQUAL_EP2(a.getLatitudeDeg(), -45.464833, 1e-4);
SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -12.576);
SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), -45.464833333);
SG_VERIFY(strutils::parseStringAsGeod("") == false);
SG_VERIFY(strutils::parseStringAsGeod("aaaaaaaa") == false);