From 2e279f7b155251e59866b8eb7da9901fe029362d Mon Sep 17 00:00:00 2001 From: cyber-toad Date: Sat, 5 Aug 2023 19:19:37 +0200 Subject: [PATCH] [gpx] Support cmt tag Signed-off-by: cyber-toad --- kml/kml_tests/gpx_tests.cpp | 22 +++++++++++++++++++++ kml/serdes_gpx.cpp | 38 +++++++++++++++++++++++++++---------- kml/serdes_gpx.hpp | 8 +++++--- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/kml/kml_tests/gpx_tests.cpp b/kml/kml_tests/gpx_tests.cpp index ddc0fd49ac..be0ef78783 100644 --- a/kml/kml_tests/gpx_tests.cpp +++ b/kml/kml_tests/gpx_tests.cpp @@ -1,6 +1,7 @@ #include "testing/testing.hpp" #include "map/bookmark_helpers.hpp" #include "kml/serdes_gpx.hpp" +#include "base/string_utils.hpp" #include "coding/string_utf8_multilang.hpp" #include "geometry/mercator.hpp" #include "platform/platform.hpp" @@ -223,5 +224,26 @@ UNIT_TEST(OsmandColor2) TEST_EQUAL(expected2, dataFromFile.m_bookmarksData[1].m_color.m_rgba, ()); } +UNIT_TEST(Gpx_Test_Cmt) +{ + std::string const input = R"( + + 1d1 + 2d2c2 + 3c3 + 4 + +d4 +d5 + + c4 + +)"; + kml::FileData const dataFromText = loadGpxFromString(input); + TEST_EQUAL("d1", dataFromText.m_bookmarksData[0].m_description.at(kml::kDefaultLang), ()); + TEST_EQUAL("d2\n\nc2", dataFromText.m_bookmarksData[1].m_description.at(kml::kDefaultLang), ()); + TEST_EQUAL("c3", dataFromText.m_bookmarksData[2].m_description.at(kml::kDefaultLang), ()); + TEST_EQUAL("d4\nd5\n\nc4", dataFromText.m_bookmarksData[3].m_description.at(kml::kDefaultLang), ()); +} \ No newline at end of file diff --git a/kml/serdes_gpx.cpp b/kml/serdes_gpx.cpp index 122c1b48ef..2d1ea1f90b 100644 --- a/kml/serdes_gpx.cpp +++ b/kml/serdes_gpx.cpp @@ -29,6 +29,7 @@ std::string_view constexpr kGarminColor = "gpxx:DisplayColor"; std::string_view constexpr kDesc = "desc"; std::string_view constexpr kMetadata = "metadata"; std::string_view constexpr kEle = "ele"; +std::string_view constexpr kCmt = "cmt"; int constexpr kInvalidColor = 0; GpxParser::GpxParser(FileData & data) @@ -42,6 +43,7 @@ void GpxParser::ResetPoint() { m_name.clear(); m_description.clear(); + m_comment.clear(); m_org = {}; m_predefinedColor = PredefinedColor::None; m_color = kInvalidColor; @@ -63,7 +65,7 @@ bool GpxParser::MakeValid() { // Set default name. if (m_name.empty()) - m_name[kml::kDefaultLang] = kml::PointToString(m_org); + m_name = kml::PointToString(m_org); // Set default pin. if (m_predefinedColor == PredefinedColor::None) @@ -227,12 +229,15 @@ void GpxParser::Pop(std::string_view tag) if (GEOMETRY_TYPE_POINT == m_geometryType) { BookmarkData data; - data.m_name = std::move(m_name); - data.m_description = std::move(m_description); + if (!m_name.empty()) + data.m_name = {{ kDefaultLang, m_name }}; + if (!m_description.empty() || !m_comment.empty()) + data.m_description = {{kDefaultLang, BuildDescription()}}; data.m_color.m_predefinedColor = m_predefinedColor; data.m_color.m_rgba = m_color; data.m_point = m_org; - data.m_customName = std::move(m_customName); + if (!m_customName.empty()) + data.m_customName = {{kDefaultLang, m_customName}}; // Here we set custom name from 'name' field for KML-files exported from 3rd-party services. if (data.m_name.size() == 1 && data.m_name.begin()->first == kDefaultLangCode && data.m_customName.empty()) data.m_customName = data.m_name; @@ -252,8 +257,10 @@ void GpxParser::Pop(std::string_view tag) m_trackLayers.push_back(std::move(layer)); TrackData data; - data.m_name = std::move(m_name); - data.m_description = std::move(m_description); + if (!m_name.empty()) + data.m_name = {{ kDefaultLang, m_name }}; + if (!m_description.empty() || !m_comment.empty()) + data.m_description = {{kDefaultLang, BuildDescription()}}; data.m_layers = std::move(m_trackLayers); data.m_geometry = std::move(m_geometry); m_data.m_tracksData.push_back(std::move(data)); @@ -286,6 +293,8 @@ void GpxParser::CharData(std::string & value) ParseColor(value); else if (currTag == gpx::kEle) ParseAltitude(value); + else if (currTag == gpx::kCmt) + m_comment = value; } } @@ -293,11 +302,11 @@ void GpxParser::ParseDescription(std::string const & value, std::string const & { if (prevTag == kWpt) { - m_description[kDefaultLang] = value; + m_description = value; } else if (prevTag == kTrk || prevTag == kRte) { - m_description[kDefaultLang] = value; + m_description = value; if (m_categoryData->m_description[kDefaultLang].empty()) m_categoryData->m_description[kDefaultLang] = value; } @@ -311,11 +320,11 @@ void GpxParser::ParseName(std::string const & value, std::string const & prevTag { if (prevTag == kWpt) { - m_name[kDefaultLang] = value; + m_name = value; } else if (prevTag == kTrk || prevTag == kRte) { - m_name[kDefaultLang] = value; + m_name = value; if (m_categoryData->m_name[kDefaultLang].empty()) m_categoryData->m_name[kDefaultLang] = value; } @@ -334,6 +343,15 @@ void GpxParser::ParseAltitude(std::string const & value) m_altitude = geometry::kInvalidAltitude; } +std::string GpxParser::BuildDescription() +{ + if (m_description.empty()) + return m_comment; + else if (m_comment.empty()) + return m_description; + return m_description + "\n\n" + m_comment; +} + } // namespace gpx DeserializerGpx::DeserializerGpx(FileData & fileData) diff --git a/kml/serdes_gpx.hpp b/kml/serdes_gpx.hpp index b807e7b5c2..9b7fae363a 100644 --- a/kml/serdes_gpx.hpp +++ b/kml/serdes_gpx.hpp @@ -55,8 +55,9 @@ private: uint32_t m_color; uint32_t m_globalColor; // To support OSMAnd extensions with single color per GPX file - LocalizableString m_name; - LocalizableString m_description; + std::string m_name; + std::string m_description; + std::string m_comment; PredefinedColor m_predefinedColor; geometry::PointWithAltitude m_org; @@ -65,11 +66,12 @@ private: geometry::Altitude m_altitude; MultiGeometry::LineT m_line; - LocalizableString m_customName; + std::string m_customName; std::vector m_trackLayers; void ParseName(std::string const & value, std::string const & prevTag); void ParseDescription(std::string const & value, std::string const & prevTag); void ParseAltitude(std::string const & value); + std::string BuildDescription(); }; } // namespace gpx