diff --git a/data/gpx_test_data/color.gpx b/data/gpx_test_data/color.gpx index 56a81bef96..0de2801302 100644 --- a/data/gpx_test_data/color.gpx +++ b/data/gpx_test_data/color.gpx @@ -77,4 +77,35 @@ + + + black + + + Black + + + + + 75.59999 + + + + + + + reset to red + + + UnussportedGarminColor + + + + + 75.59999 + + + + + \ No newline at end of file diff --git a/kml/kml_tests/gpx_tests.cpp b/kml/kml_tests/gpx_tests.cpp index 8b0b53822a..9e97e8360f 100644 --- a/kml/kml_tests/gpx_tests.cpp +++ b/kml/kml_tests/gpx_tests.cpp @@ -132,8 +132,13 @@ UNIT_TEST(Route) UNIT_TEST(Color) { kml::FileData const dataFromFile = loadGpxFromFile("gpx_test_data/color.gpx"); - TEST_EQUAL(4278190335, dataFromFile.m_tracksData[0].m_layers[0].m_color.m_rgba, ()); - TEST_EQUAL(65535, dataFromFile.m_tracksData[1].m_layers[0].m_color.m_rgba, ()); + uint32_t const red = 0xFF0000FF; + uint32_t const blue = 0x0000FFFF; + uint32_t const black = 0x000000FF; + TEST_EQUAL(red, dataFromFile.m_tracksData[0].m_layers[0].m_color.m_rgba, ()); + TEST_EQUAL(blue, dataFromFile.m_tracksData[1].m_layers[0].m_color.m_rgba, ()); + TEST_EQUAL(black, dataFromFile.m_tracksData[2].m_layers[0].m_color.m_rgba, ()); + TEST_EQUAL(red, dataFromFile.m_tracksData[3].m_layers[0].m_color.m_rgba, ()); } UNIT_TEST(MultiTrackNames) diff --git a/kml/serdes_gpx.cpp b/kml/serdes_gpx.cpp index cc91312f8e..940e6eb74b 100644 --- a/kml/serdes_gpx.cpp +++ b/kml/serdes_gpx.cpp @@ -27,6 +27,7 @@ std::string_view constexpr kWpt = "wpt"; std::string_view constexpr kRtePt = "rtept"; std::string_view constexpr kName = "name"; std::string_view constexpr kColor = "color"; +std::string_view constexpr kGarminColor = "gpxx:DisplayColor"; std::string_view constexpr kDesc = "desc"; std::string_view constexpr kMetadata = "metadata"; @@ -139,6 +140,41 @@ void GpxParser::ParseColor(std::string const & value) m_color = kml::ToRGBA(colorBytes[0], colorBytes[1], colorBytes[2], (char)255); } + +// Garmin extensions spec: https://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd +// Color mapping: https://help.locusmap.eu/topic/extend-garmin-gpx-compatibilty +void GpxParser::ParseGarminColor(std::string const & v) +{ + static std::unordered_map const kGarminToHex = { + {"Black", "000000"}, + {"DarkRed", "8b0000"}, + {"DarkGreen", "006400"}, + {"DarkYellow", "b5b820"}, + {"DarkBlue", "00008b"}, + {"DarkMagenta", "8b008b"}, + {"DarkCyan", "008b8b"}, + {"LightGray", "cccccc"}, + {"DarkGray", "444444"}, + {"Red", "ff0000"}, + {"Green", "00ff00"}, + {"Yellow", "ffff00"}, + {"Blue", "0000ff"}, + {"Magenta", "ff00ff"}, + {"Cyan", "00ffff"}, + {"White", "ffffff"}, + {"Transparent", "ff0000"} + }; + auto const it = kGarminToHex.find(v); + if (it != kGarminToHex.end()) { + return ParseColor(it->second); + } + else + { + LOG(LWARNING, ("Unsupported color value", v)); + return ParseColor("ff0000"); // default to red + } +} + void GpxParser::Pop(std::string_view tag) { ASSERT_EQUAL(m_tags.back(), tag, ()); @@ -238,6 +274,8 @@ void GpxParser::CharData(std::string value) } if (currTag == gpx::kColor) ParseColor(value); + else if (currTag == gpx::kGarminColor) + ParseGarminColor(value); } } } // namespace gpx diff --git a/kml/serdes_gpx.hpp b/kml/serdes_gpx.hpp index 0c118920aa..05f4973391 100644 --- a/kml/serdes_gpx.hpp +++ b/kml/serdes_gpx.hpp @@ -41,6 +41,7 @@ private: void ResetPoint(); bool MakeValid(); void ParseColor(std::string const & value); + void ParseGarminColor(std::string const & value); FileData & m_data; CategoryData m_compilationData;