From 9612beaaf003d66c73559d9b5edbe34650a13df8 Mon Sep 17 00:00:00 2001 From: Andrew Shkrob Date: Sun, 12 Mar 2023 21:02:04 +0100 Subject: [PATCH] [kml] Correctly import bookmarks with track data Closes: #3467 Signed-off-by: Andrew Shkrob --- kml/kml_tests/serdes_tests.cpp | 43 ++++++++++++++++++++++++++++++++++ kml/serdes.cpp | 23 ++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/kml/kml_tests/serdes_tests.cpp b/kml/kml_tests/serdes_tests.cpp index 27fb9b59ee..de52af7bf7 100644 --- a/kml/kml_tests/serdes_tests.cpp +++ b/kml/kml_tests/serdes_tests.cpp @@ -874,3 +874,46 @@ UNIT_TEST(Kml_Ver_2_3) TEST_EQUAL(lines[0].size(), 7, ()); TEST_EQUAL(lines[1].size(), 6, ()); } + +UNIT_TEST(Kml_Placemark_contains_both_Bookmark_and_Track_data) +{ + char const * input = R"( + + + + + 28.968447783842,41.009030507129,0 + + + 28.968447783842,41.009030507129,0 28.965858,41.018449,0 + + + + + + + 28.968447783842,41.009030507129,0 28.965858,41.018449,0 + + + 28.968447783842,41.009030507129,0 + + + + + )"; + + kml::FileData fData; + try + { + MemReader reader(input, strlen(input)); + kml::DeserializerKml des(fData); + des.Deserialize(reader); + } + catch (kml::DeserializerKml::DeserializeException const & ex) + { + TEST(false, ("Exception raised", ex.Msg())); + } + + TEST_EQUAL(fData.m_bookmarksData.size(), 2, ()); + TEST_EQUAL(fData.m_tracksData.size(), 2, ()); +} diff --git a/kml/serdes.cpp b/kml/serdes.cpp index 9991fe0745..8bb1b944a2 100644 --- a/kml/serdes.cpp +++ b/kml/serdes.cpp @@ -734,7 +734,7 @@ void KmlParser::ParseAndAddPoints(MultiGeometry::LineT & line, std::string_view geometry::PointWithAltitude point; if (ParsePointWithAltitude(v, coordSeparator, point)) { - // We dont't expect vertical surfaces, so do not compare heights here. + // We don't expect vertical surfaces, so do not compare heights here. // Will get a lot of duplicating points otherwise after import some user KMLs. // https://github.com/organicmaps/organicmaps/issues/3895 if (line.empty() || !AlmostEqualAbs(line.back().GetPoint(), point.GetPoint(), kMwmPointAccuracy)) @@ -745,7 +745,9 @@ void KmlParser::ParseAndAddPoints(MultiGeometry::LineT & line, std::string_view void KmlParser::ParseLineString(std::string const & s) { - m_geometryType = GEOMETRY_TYPE_LINE; + // If m_org is not empty, then it's still a Bookmark but with track data + if (m_org == m2::PointD::Zero()) + m_geometryType = GEOMETRY_TYPE_LINE; MultiGeometry::LineT line; ParseAndAddPoints(line, s, " \n\r\t", ","); @@ -934,6 +936,23 @@ void KmlParser::Pop(std::string const & tag) } m_data.m_bookmarksData.push_back(std::move(data)); + + // There is a track stored inside a bookmark + if (m_geometry.IsValid()) + { + BookmarkData const & bookmarkData = m_data.m_bookmarksData.back(); + TrackData trackData; + trackData.m_localId = m_localId; + trackData.m_name = bookmarkData.m_name; + trackData.m_description = bookmarkData.m_description; + trackData.m_layers = std::move(m_trackLayers); + trackData.m_timestamp = m_timestamp; + trackData.m_geometry = std::move(m_geometry); + trackData.m_visible = m_visible; + trackData.m_nearestToponyms = std::move(m_nearestToponyms); + trackData.m_properties = bookmarkData.m_properties; + m_data.m_tracksData.push_back(std::move(trackData)); + } } else if (GEOMETRY_TYPE_LINE == m_geometryType) {