diff --git a/map/framework.cpp b/map/framework.cpp index 8af03b9245..5c30ddf9f6 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -28,6 +28,8 @@ #include "../std/target_os.hpp" #include "../std/vector.hpp" +#include + void Framework::AddMap(string const & file) { @@ -290,13 +292,25 @@ namespace } } - void CharData(string const & value) + class IsSpace { - switch (m_level) + public: + bool operator() (char c) const { - case 4: m_name = value; break; - case 5: SetOrigin(value); break; + return ::isspace(c); } + }; + + void CharData(string value) + { + boost::trim(value); + + if (!value.empty()) + switch (m_level) + { + case 4: m_name = value; break; + case 5: SetOrigin(value); break; + } } }; } @@ -308,6 +322,49 @@ void Framework::LoadFromKML(ReaderPtr const & reader) ParseXML(src, parser, true); } +namespace +{ +char const * kmlHeader = + "\n" + "\n" + "\n" + " MapsWithMe\n"; + +char const * kmlFooter = + "\n" + "\n"; + +string PointToString(m2::PointD const & org) +{ + double const lon = MercatorBounds::XToLon(org.x); + double const lat = MercatorBounds::YToLat(org.y); + + ostringstream ss; + ss.precision(8); + + ss << lon << "," << lat; + return ss.str(); +} + +} + +void Framework::SaveToKML(std::ostream & s) +{ + s << kmlHeader; + + for (list::const_iterator i = m_bookmarks.begin(); i != m_bookmarks.end(); ++i) + { + s << " \n" + << " " << i->GetName() << "\n" + << " \n" + << " " << PointToString(i->GetOrg()) << "\n" + << " \n" + << " \n"; + } + + s << kmlFooter; +} + void Framework::GetLocalMaps(vector & outMaps) { Platform & pl = GetPlatform(); diff --git a/map/framework.hpp b/map/framework.hpp index efcb274aa0..bf5032f186 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -130,6 +130,7 @@ public: void ClearBookmarks(); void LoadFromKML(ReaderPtr const & reader); + void SaveToKML(std::ostream & s); storage::Storage & Storage() { return m_storage; } diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp index 88c606a9ad..9459a7b2c4 100644 --- a/map/map_tests/bookmarks_test.cpp +++ b/map/map_tests/bookmarks_test.cpp @@ -2,6 +2,8 @@ #include "../../map/framework.hpp" +#include "../../std/fstream.hpp" + namespace { @@ -51,24 +53,49 @@ char const * kmlString = "" "" ""; + + void CheckBookmarks(Framework const & fm) + { + TEST_EQUAL(fm.BookmarksCount(), 3, ()); + + Bookmark bm; + fm.GetBookmark(0, bm); + TEST_EQUAL(bm.GetName(), "Nebraska", ()); + fm.GetBookmark(1, bm); + TEST_EQUAL(bm.GetName(), "Monongahela National Forest", ()); + + fm.GetBookmark(2, bm); + m2::PointD const org = bm.GetOrg(); + TEST_ALMOST_EQUAL(MercatorBounds::XToLon(org.x), 27.566765, ()); + TEST_ALMOST_EQUAL(MercatorBounds::YToLat(org.y), 53.900047, ()); + } } UNIT_TEST(Bookmarks_ImportKML) { Framework fm; - fm.LoadFromKML(new MemReader(kmlString, strlen(kmlString))); - TEST_EQUAL(fm.BookmarksCount(), 3, ()); - - Bookmark bm; - fm.GetBookmark(0, bm); - TEST_EQUAL(bm.GetName(), "Nebraska", ()); - fm.GetBookmark(1, bm); - TEST_EQUAL(bm.GetName(), "Monongahela National Forest", ()); - - fm.GetBookmark(2, bm); - m2::PointD const org = bm.GetOrg(); - TEST_ALMOST_EQUAL(MercatorBounds::XToLon(org.x), 27.566765, ()); - TEST_ALMOST_EQUAL(MercatorBounds::YToLat(org.y), 53.900047, ()); + CheckBookmarks(fm); +} + +UNIT_TEST(Bookmarks_ExportKML) +{ + Framework fm; + fm.LoadFromKML(new MemReader(kmlString, strlen(kmlString))); + + CheckBookmarks(fm); + + { + ofstream of("Bookmarks.kml"); + fm.SaveToKML(of); + } + + fm.ClearBookmarks(); + + TEST_EQUAL(fm.BookmarksCount(), 0, ()); + + fm.LoadFromKML(new FileReader("Bookmarks.kml")); + + CheckBookmarks(fm); }