forked from organicmaps/organicmaps
Save bookmarks viewport scale when adding.
This commit is contained in:
parent
79c59a474a
commit
12b8678ae3
6 changed files with 134 additions and 77 deletions
|
@ -6,8 +6,8 @@
|
|||
#import "CompassView.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../../geometry/distance_on_sphere.hpp"
|
||||
#include "../../../platform/platform.hpp"
|
||||
|
||||
|
||||
@implementation BookmarksVC
|
||||
|
@ -48,7 +48,7 @@
|
|||
{
|
||||
BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex);
|
||||
cat->SetVisible(sender.on);
|
||||
cat->SaveToKMLFileAtPath(GetPlatform().WritableDir());
|
||||
cat->SaveToKMLFile();
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
@ -153,7 +153,7 @@
|
|||
else
|
||||
{
|
||||
Framework & f = GetFramework();
|
||||
BookmarkCategory * cat = f.GetBmCategory(m_categoryIndex);
|
||||
BookmarkCategory const * cat = f.GetBmCategory(m_categoryIndex);
|
||||
if (cat)
|
||||
{
|
||||
Bookmark const * bm = cat->GetBookmark(indexPath.row);
|
||||
|
@ -162,7 +162,7 @@
|
|||
// Same as "Close".
|
||||
[self dismissModalViewControllerAnimated:YES];
|
||||
[self.navigationController.visibleViewController dismissModalViewControllerAnimated:YES];
|
||||
f.ShowRectExVisibleScale(bm->GetViewport());
|
||||
f.ShowBookmark(*bm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
111
map/bookmark.cpp
111
map/bookmark.cpp
|
@ -2,11 +2,10 @@
|
|||
|
||||
#include "../indexer/mercator.hpp"
|
||||
|
||||
#include "../platform/platform.hpp"
|
||||
|
||||
#include "../coding/file_reader.hpp"
|
||||
#include "../coding/parse_xml.hpp" // LoadFromKML
|
||||
#include "../base/string_utils.hpp"
|
||||
|
||||
#include "../platform/platform.hpp"
|
||||
|
||||
#include "../base/stl_add.hpp"
|
||||
#include "../base/string_utils.hpp"
|
||||
|
@ -15,19 +14,30 @@
|
|||
#include "../std/algorithm.hpp"
|
||||
|
||||
|
||||
void BookmarkCategory::AddBookmark(Bookmark const & bm)
|
||||
void BookmarkCategory::AddBookmark(Bookmark const & bm, double scale)
|
||||
{
|
||||
m_bookmarks.push_back(new Bookmark(bm));
|
||||
Bookmark * p = new Bookmark(bm);
|
||||
p->SetScale(scale);
|
||||
|
||||
m_bookmarks.push_back(p);
|
||||
|
||||
VERIFY ( SaveToKMLFile(), () );
|
||||
}
|
||||
|
||||
void BookmarkCategory::ReplaceBookmark(size_t index, Bookmark const & bm)
|
||||
void BookmarkCategory::ReplaceBookmark(size_t index, Bookmark const & bm, double scale)
|
||||
{
|
||||
ASSERT_LESS(index, m_bookmarks.size(), ());
|
||||
ASSERT_LESS ( index, m_bookmarks.size(), () );
|
||||
if (index < m_bookmarks.size())
|
||||
{
|
||||
Bookmark * p = new Bookmark(bm);
|
||||
p->SetScale(scale);
|
||||
|
||||
Bookmark const * old = m_bookmarks[index];
|
||||
m_bookmarks[index] = new Bookmark(bm);
|
||||
m_bookmarks[index] = p;
|
||||
|
||||
delete old;
|
||||
|
||||
VERIFY ( SaveToKMLFile(), () );
|
||||
}
|
||||
else
|
||||
LOG(LWARNING, ("Trying to replace non-existing bookmark"));
|
||||
|
@ -50,9 +60,8 @@ void BookmarkCategory::DeleteBookmark(size_t index)
|
|||
{
|
||||
delete m_bookmarks[index];
|
||||
m_bookmarks.erase(m_bookmarks.begin() + index);
|
||||
// Save updated file
|
||||
if (!m_file.empty())
|
||||
(void)SaveToKMLFileAtPath(m_file);
|
||||
|
||||
VERIFY ( SaveToKMLFile(), () );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,17 +89,20 @@ namespace
|
|||
// Fixes icons which are not supported by MapsWithMe
|
||||
static string GetSupportedBMType(string const & s)
|
||||
{
|
||||
static char const * icons[] = {"placemark-red", "placemark-blue", "placemark-purple",
|
||||
"placemark-pink", "placemark-brown", "placemark-green", "placemark-orange"};
|
||||
static char const * icons[] = {
|
||||
"placemark-red", "placemark-blue", "placemark-purple",
|
||||
"placemark-pink", "placemark-brown", "placemark-green", "placemark-orange"
|
||||
};
|
||||
|
||||
// Remove leading '#' symbol
|
||||
string result = s.substr(1);
|
||||
string const result = s.substr(1);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(icons); ++i)
|
||||
if (result == icons[i])
|
||||
return result;
|
||||
|
||||
// Not recognized symbols are replaced with default one
|
||||
LOG(LWARNING, ("Bookmark icon is not supported:", result));
|
||||
return "placemark-red";
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
class KMLParser
|
||||
|
@ -103,12 +115,14 @@ namespace
|
|||
string m_type;
|
||||
|
||||
m2::PointD m_org;
|
||||
double m_scale;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_name.clear();
|
||||
m_org = m2::PointD(-1000, -1000);
|
||||
m_type.clear();
|
||||
m_scale = -1.0;
|
||||
}
|
||||
|
||||
void SetOrigin(string const & s)
|
||||
|
@ -156,43 +170,49 @@ namespace
|
|||
|
||||
if (tag == "Placemark" && IsValid())
|
||||
{
|
||||
m_category.AddBookmark(Bookmark(m_org, m_name, m_type));
|
||||
m_category.AddBookmark(Bookmark(m_org, m_name, m_type), m_scale);
|
||||
Reset();
|
||||
}
|
||||
m_tags.pop_back();
|
||||
}
|
||||
|
||||
class IsSpace
|
||||
{
|
||||
public:
|
||||
bool operator() (char c) const
|
||||
{
|
||||
return ::isspace(c);
|
||||
}
|
||||
};
|
||||
|
||||
void CharData(string value)
|
||||
{
|
||||
strings::Trim(value);
|
||||
|
||||
size_t const count = m_tags.size();
|
||||
if (count > 1 && !value.empty())
|
||||
{
|
||||
string const & currTag = m_tags[count - 1];
|
||||
string const & prevTag = m_tags[count - 2];
|
||||
|
||||
if (currTag == "name")
|
||||
if (prevTag == "Document")
|
||||
{
|
||||
if (prevTag == "Placemark")
|
||||
m_name = value;
|
||||
else if (prevTag == "Document")
|
||||
if (currTag == "name")
|
||||
m_category.SetName(value);
|
||||
else if (currTag == "visibility")
|
||||
m_category.SetVisible(value == "0" ? false : true);
|
||||
}
|
||||
else if (prevTag == "Placemark")
|
||||
{
|
||||
if (currTag == "name")
|
||||
m_name = value;
|
||||
else if (currTag == "styleUrl")
|
||||
m_type = GetSupportedBMType(value);
|
||||
}
|
||||
else if (prevTag == "Point")
|
||||
{
|
||||
if (currTag == "coordinates")
|
||||
SetOrigin(value);
|
||||
}
|
||||
else if (prevTag == "ExtendedData")
|
||||
{
|
||||
if (currTag == "mwm:scale")
|
||||
{
|
||||
if (!strings::to_double(value, m_scale))
|
||||
m_scale = -1.0;
|
||||
}
|
||||
}
|
||||
else if (currTag == "coordinates" && prevTag == "Point")
|
||||
SetOrigin(value);
|
||||
else if (currTag == "visibility" && prevTag == "Document")
|
||||
m_category.SetVisible(value == "0" ? false : true);
|
||||
else if (currTag == "styleUrl" && prevTag == "Placemark")
|
||||
m_type = GetSupportedBMType(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -312,8 +332,18 @@ void BookmarkCategory::SaveToKML(ostream & s)
|
|||
<< " <styleUrl>#" << bm->GetType() << "</styleUrl>\n"
|
||||
<< " <Point>\n"
|
||||
<< " <coordinates>" << PointToString(bm->GetOrg()) << "</coordinates>\n"
|
||||
<< " </Point>\n"
|
||||
<< " </Placemark>\n";
|
||||
<< " </Point>\n";
|
||||
|
||||
double const scale = bm->GetScale();
|
||||
if (scale != -1)
|
||||
{
|
||||
/// @todo Factor out to separate function to use for other custom params.
|
||||
s << " <ExtendedData xmlns:mwm=\"http://mapswithme.com\">\n"
|
||||
<< " <mwm:scale>" << bm->GetScale() << "</mwm:scale>\n"
|
||||
<< " </ExtendedData>\n";
|
||||
}
|
||||
|
||||
s << " </Placemark>\n";
|
||||
}
|
||||
|
||||
s << kmlFooter;
|
||||
|
@ -346,10 +376,13 @@ string BookmarkCategory::GenerateUniqueFileName(const string & path, string cons
|
|||
return path + fixedName + suffix + ".kml";
|
||||
}
|
||||
|
||||
bool BookmarkCategory::SaveToKMLFileAtPath(string const & path)
|
||||
bool BookmarkCategory::SaveToKMLFile()
|
||||
{
|
||||
if (m_file.empty())
|
||||
m_file = GenerateUniqueFileName(path, m_file);
|
||||
{
|
||||
/// @todo It's better to pass category name as file name here, isn't it?
|
||||
m_file = GenerateUniqueFileName(GetPlatform().WritableDir(), m_file);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -14,8 +14,8 @@ class Bookmark
|
|||
{
|
||||
m2::PointD m_org;
|
||||
string m_name;
|
||||
/// Now it stores bookmark color
|
||||
string m_type;
|
||||
string m_type; ///< Now it stores bookmark color (category style).
|
||||
double m_scale; ///< Viewport scale. -1.0 - is a default value (no scale set).
|
||||
|
||||
public:
|
||||
Bookmark() {}
|
||||
|
@ -26,9 +26,12 @@ public:
|
|||
|
||||
m2::PointD GetOrg() const { return m_org; }
|
||||
string const & GetName() const { return m_name; }
|
||||
/// Now it returns bookmark color
|
||||
/// @return Now its a bookmark color.
|
||||
string const & GetType() const { return m_type; }
|
||||
m2::RectD GetViewport() const { return m2::RectD(m_org, m_org); }
|
||||
|
||||
double GetScale() const { return m_scale; }
|
||||
void SetScale(double scale) { m_scale = scale; }
|
||||
};
|
||||
|
||||
class BookmarkCategory : private noncopyable
|
||||
|
@ -45,32 +48,43 @@ public:
|
|||
|
||||
void ClearBookmarks();
|
||||
|
||||
void AddBookmark(Bookmark const & bm);
|
||||
/// @name This function are called from Framework only.
|
||||
//@{
|
||||
void AddBookmark(Bookmark const & bm, double scale);
|
||||
void ReplaceBookmark(size_t index, Bookmark const & bm, double scale);
|
||||
//@}
|
||||
|
||||
void SetVisible(bool isVisible) { m_visible = isVisible; }
|
||||
bool IsVisible() const { return m_visible; }
|
||||
|
||||
void SetName(string const & name) { m_name = name; }
|
||||
string GetName() const { return m_name; }
|
||||
string GetFileName() const { return m_file; }
|
||||
|
||||
inline size_t GetBookmarksCount() const { return m_bookmarks.size(); }
|
||||
|
||||
Bookmark const * GetBookmark(size_t index) const;
|
||||
/// @param[in] distance in metres between orgs
|
||||
/// @returns -1 or index of found bookmark
|
||||
int GetBookmark(m2::PointD const org, double const squareDistance) const;
|
||||
void DeleteBookmark(size_t index);
|
||||
void ReplaceBookmark(size_t index, Bookmark const & bm);
|
||||
|
||||
void DeleteBookmark(size_t index);
|
||||
|
||||
/// @name This fuctions are public for unit tests only.
|
||||
/// You don't need to call them from client code.
|
||||
//@{
|
||||
void LoadFromKML(ReaderPtr<Reader> const & reader);
|
||||
void SaveToKML(ostream & s);
|
||||
|
||||
/// Uses the same file name from which was loaded, or
|
||||
/// creates unique file name on first save and uses it every time.
|
||||
bool SaveToKMLFile();
|
||||
|
||||
/// @return 0 in the case of error
|
||||
static BookmarkCategory * CreateFromKMLFile(string const & file);
|
||||
/// Uses the same file name from which was loaded, or
|
||||
/// creates unique file name on first save and uses it every time
|
||||
/// @param[in] path directory name where to save
|
||||
bool SaveToKMLFileAtPath(string const & path);
|
||||
|
||||
static string GenerateUniqueFileName(const string & path, string const & name);
|
||||
//@}
|
||||
};
|
||||
|
||||
/// <category index, bookmark index>
|
||||
|
|
|
@ -221,6 +221,11 @@ Framework::~Framework()
|
|||
ClearBookmarks();
|
||||
}
|
||||
|
||||
double Framework::GetVisualScale() const
|
||||
{
|
||||
return (m_renderPolicy ? m_renderPolicy->VisualScale() : 1);
|
||||
}
|
||||
|
||||
void Framework::DeleteCountry(TIndex const & index)
|
||||
{
|
||||
if (!m_storage.DeleteFromDownloader(index))
|
||||
|
@ -321,6 +326,10 @@ void Framework::LoadBookmarks()
|
|||
|
||||
void Framework::AddBookmark(string const & category, Bookmark const & bm)
|
||||
{
|
||||
// Get global non-rotated viewport rect and calculate viewport scale level.
|
||||
double const scale = scales::GetScaleLevelD(
|
||||
m_navigator.Screen().GlobalRect().GetLocalRect());
|
||||
|
||||
// @TODO not optimal for 1st release
|
||||
// Existing bookmark can be moved from one category to another,
|
||||
// or simply replaced in the same category,
|
||||
|
@ -330,15 +339,13 @@ void Framework::AddBookmark(string const & category, Bookmark const & bm)
|
|||
{
|
||||
m2::PointD const org = bm.GetOrg();
|
||||
BookmarkCategory * cat = m_bookmarks[i];
|
||||
int index = cat->GetBookmark(org, squareDistance);
|
||||
int const index = cat->GetBookmark(org, squareDistance);
|
||||
if (index >= 0)
|
||||
{
|
||||
// found bookmark to replace
|
||||
if (category == cat->GetName())
|
||||
{
|
||||
cat->ReplaceBookmark(static_cast<size_t>(index), bm);
|
||||
// Autosave added bookmark
|
||||
(void)cat->SaveToKMLFileAtPath(GetPlatform().WritableDir());
|
||||
cat->ReplaceBookmark(static_cast<size_t>(index), bm, scale);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -350,10 +357,7 @@ void Framework::AddBookmark(string const & category, Bookmark const & bm)
|
|||
}
|
||||
|
||||
BookmarkCategory * cat = GetBmCategory(category);
|
||||
ASSERT(cat, ("category should autocreate if not exists"));
|
||||
cat->AddBookmark(bm);
|
||||
// Autosave added bookmark
|
||||
(void)cat->SaveToKMLFileAtPath(GetPlatform().WritableDir());
|
||||
cat->AddBookmark(bm, scale);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -403,15 +407,12 @@ bool Framework::DeleteBmCategory(size_t index)
|
|||
else return false;
|
||||
}
|
||||
|
||||
BookmarkAndCategory Framework::GetBookmark(m2::PointD pt) const
|
||||
BookmarkAndCategory Framework::GetBookmark(m2::PointD const & pxPoint) const
|
||||
{
|
||||
// @TODO Refactor. Why bookmarks can't be retrieved? Change pixel point to global point.
|
||||
if (m_renderPolicy == 0)
|
||||
return MakeEmptyBookmarkAndCategory();
|
||||
return GetBookmark(pt, m_renderPolicy->VisualScale());
|
||||
return GetBookmark(pxPoint, GetVisualScale());
|
||||
}
|
||||
|
||||
BookmarkAndCategory Framework::GetBookmark(m2::PointD pxPoint, double visualScale) const
|
||||
BookmarkAndCategory Framework::GetBookmark(m2::PointD const & pxPoint, double visualScale) const
|
||||
{
|
||||
// Get the global rect of touching area.
|
||||
int const sm = TOUCH_PIXEL_RADIUS * visualScale;
|
||||
|
@ -446,6 +447,14 @@ BookmarkAndCategory Framework::GetBookmark(m2::PointD pxPoint, double visualScal
|
|||
return make_pair(retBookmarkCategory, retBookmark);
|
||||
}
|
||||
|
||||
void Framework::ShowBookmark(Bookmark const & bm)
|
||||
{
|
||||
double scale = bm.GetScale();
|
||||
if (scale == -1.0) scale = 16.0;
|
||||
|
||||
ShowRectExVisibleScale(scales::GetRectForLevel(scale, bm.GetOrg(), 1.0));
|
||||
}
|
||||
|
||||
void Framework::ClearBookmarks()
|
||||
{
|
||||
for_each(m_bookmarks.begin(), m_bookmarks.end(), DeleteFunctor());
|
||||
|
@ -1346,14 +1355,8 @@ shared_ptr<yg::OverlayElement> const GetClosestToPivot(list<shared_ptr<yg::Overl
|
|||
|
||||
bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot, AddressInfo & info) const
|
||||
{
|
||||
if (!m_renderPolicy)
|
||||
{
|
||||
LOG(LINFO, ("GetVisiblePOI called without valid renderPolicy!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
m2::PointD const pt = m_navigator.ShiftPoint(pxPoint);
|
||||
double const halfSize = TOUCH_PIXEL_RADIUS * m_renderPolicy->VisualScale();
|
||||
double const halfSize = TOUCH_PIXEL_RADIUS * GetVisualScale();
|
||||
|
||||
typedef yg::OverlayElement ElementT;
|
||||
|
||||
|
|
|
@ -78,6 +78,11 @@ protected:
|
|||
|
||||
scoped_ptr<RenderPolicy> m_renderPolicy;
|
||||
|
||||
/// Safe function to get current visual scale.
|
||||
/// Call it when you need do calculate pixel rect (not matter if m_renderPolicy == 0).
|
||||
/// @return 1.0 if m_renderPolicy == 0 (possible for Android).
|
||||
double GetVisualScale() const;
|
||||
|
||||
double m_StartForegroundTime;
|
||||
|
||||
/// @todo Need deep analyzing in future.
|
||||
|
@ -180,8 +185,10 @@ public:
|
|||
/// Get bookmark by touch.
|
||||
/// @param[in] pixPt Coordinates of touch point in pixels.
|
||||
/// @return NULL If there is no bookmark found
|
||||
BookmarkAndCategory GetBookmark(m2::PointD pixPt) const;
|
||||
BookmarkAndCategory GetBookmark(m2::PointD pixPt, double visualScale) const;
|
||||
BookmarkAndCategory GetBookmark(m2::PointD const & pxPoint) const;
|
||||
BookmarkAndCategory GetBookmark(m2::PointD const & pxPoint, double visualScale) const;
|
||||
|
||||
void ShowBookmark(Bookmark const & bm);
|
||||
|
||||
void ClearBookmarks();
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ UNIT_TEST(Bookmarks_ExportKML)
|
|||
CheckBookmarks(*cat2);
|
||||
FileWriter::DeleteFileX(BOOKMARKS_FILE_NAME);
|
||||
|
||||
cat2->SaveToKMLFileAtPath("./");
|
||||
cat2->SaveToKMLFile();
|
||||
delete cat2;
|
||||
|
||||
cat2 = BookmarkCategory::CreateFromKMLFile(BOOKMARKS_FILE_NAME);
|
||||
|
|
Loading…
Add table
Reference in a new issue