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;