diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index 1de78be5..b15a73e7 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -1379,6 +1379,35 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, case LatLonFormat::DECIMAL_DEGREES_SYMBOL: ::snprintf(buf, sizeof(buf), "%3.6f%s%c", deg, degSym, c); break; + + case LatLonFormat::ICAO_ROUTE_DEGREES: + { + min = (deg - int(deg)) * 60.0; + if (min >= 59.9995) { + min -= 60.0; + deg += 1.0; + } + + if (static_cast(min) == 0) { + // 7-digit mode + if (c == 'N' || c == 'S') { + snprintf(buf, sizeof(buf), "%02d%c", int(deg), c); + } else { + snprintf(buf, sizeof(buf), "%03d%c", int(deg), c); + } + } else { + // 11-digit mode + if (c == 'N' || c == 'S') { + snprintf(buf, sizeof(buf), "%02d%02d%c", int(deg), int(min), c); + } else { + snprintf(buf, sizeof(buf), "%03d%02d%c", int(deg), int(min), c); + } + } + break; + } + + default: + break; } return std::string(buf); @@ -1390,6 +1419,12 @@ std::string formatGeodAsString(const SGGeod& geod, LatLonFormat format, const char ns = (geod.getLatitudeDeg() > 0.0) ? 'N' : 'S'; const char ew = (geod.getLongitudeDeg() > 0.0) ? 'E' : 'W'; + // no comma seperator + if (format == LatLonFormat::ICAO_ROUTE_DEGREES) { + return formatLatLonValueAsString(geod.getLatitudeDeg(), format, ns, degreeSymbol) + + formatLatLonValueAsString(geod.getLongitudeDeg(), format, ew, degreeSymbol); + } + return formatLatLonValueAsString(geod.getLatitudeDeg(), format, ns, degreeSymbol) + "," + formatLatLonValueAsString(geod.getLongitudeDeg(), format, ew, degreeSymbol); } diff --git a/simgear/misc/strutils.hxx b/simgear/misc/strutils.hxx index f4b14558..74fb7f39 100644 --- a/simgear/misc/strutils.hxx +++ b/simgear/misc/strutils.hxx @@ -396,7 +396,8 @@ namespace simgear { ZERO_PAD_DEGREES_MINUTES, ZERO_PAD_DEGREES_MINUTES_SECONDS, TRINITY_HOUSE, ///< dd* mm'.mmm X, ddd* mm'.mmm X (Trinity House Navigation standard). - DECIMAL_DEGREES_SYMBOL ///< 88.4*N,4.54*W + DECIMAL_DEGREES_SYMBOL, ///< 88.4*N,4.54*W + ICAO_ROUTE_DEGREES, ///< 52N045W or 5212N04512W - precision auto-selected }; enum class DegreeSymbol diff --git a/simgear/misc/strutils_test.cxx b/simgear/misc/strutils_test.cxx index 07ff8c1c..35ac5b79 100644 --- a/simgear/misc/strutils_test.cxx +++ b/simgear/misc/strutils_test.cxx @@ -684,6 +684,14 @@ void test_formatGeod() SG_CHECK_EQUAL(strutils::formatGeodAsString(a, strutils::LatLonFormat::SIGNED_DECIMAL_DEGREES), "55.450000,-3.460000"); SG_CHECK_EQUAL(strutils::formatGeodAsString(a, strutils::LatLonFormat::DEGREES_MINUTES_SECONDS), "55*27'00.0\"N,3*27'36.0\"W"); + + + SG_CHECK_EQUAL(strutils::formatGeodAsString(a, strutils::LatLonFormat::ICAO_ROUTE_DEGREES), + "5527N00327W"); + SGGeod shortA = SGGeod::fromDeg(106, -34); + SG_CHECK_EQUAL(strutils::formatGeodAsString(shortA, strutils::LatLonFormat::ICAO_ROUTE_DEGREES), + "34S106E"); + const auto s = strutils::formatGeodAsString(a, strutils::LatLonFormat::ZERO_PAD_DEGREES_MINUTES, @@ -696,6 +704,8 @@ void test_formatGeod() strutils::LatLonFormat::DECIMAL_DEGREES_SYMBOL, strutils::DegreeSymbol::UTF8_DEGREE); SG_CHECK_EQUAL(s2, "6.156800\xC2\xB0S,106.827800\xC2\xB0" "E"); + + } int main(int argc, char* argv[])