forked from organicmaps/organicmaps
Add BookmarkCategory.
This commit is contained in:
parent
0218b4973e
commit
18b6f31366
11 changed files with 359 additions and 269 deletions
|
@ -1,9 +1,14 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
class BookmarkCategory;
|
||||
|
||||
@interface BookmarksVC : UIViewController<UITableViewDelegate, UITableViewDataSource>
|
||||
{
|
||||
UITableView * m_table;
|
||||
// Needed to change Edit/Cancel buttons
|
||||
UINavigationItem * m_navItem;
|
||||
|
||||
// Current category to show.
|
||||
BookmarkCategory * m_category;
|
||||
}
|
||||
@end
|
||||
@end
|
||||
|
|
|
@ -21,16 +21,10 @@
|
|||
m_navItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(onCancelEdit)] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithFramework:(Framework *)f
|
||||
{
|
||||
if ((self = [super initWithNibName:nil bundle:nil]))
|
||||
{
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
// TODO Initialize and change m_category.
|
||||
|
||||
UIView * parentView = [[[CustomNavigationView alloc] init] autorelease];
|
||||
parentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
|
||||
|
||||
|
@ -39,7 +33,7 @@
|
|||
m_navItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Maps", @"Bookmarks - Close bookmarks button") style: UIBarButtonItemStyleDone
|
||||
target:self action:@selector(onCloseButton:)] autorelease];
|
||||
// Display Edit button only if table is not empty
|
||||
if (GetFramework().BookmarksCount())
|
||||
if (m_category->GetBookmarksCount() > 0)
|
||||
{
|
||||
[self.editButtonItem setTarget:self];
|
||||
[self.editButtonItem setAction:@selector(onEdit)];
|
||||
|
@ -78,7 +72,7 @@
|
|||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
// Return the number of rows in the section.
|
||||
return GetFramework().BookmarksCount();
|
||||
return m_category->GetBookmarksCount();
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
@ -87,10 +81,9 @@
|
|||
if (!cell)
|
||||
cell = [[[SearchCell alloc] initWithReuseIdentifier:@"FeatureCell"] autorelease];
|
||||
|
||||
Bookmark bm;
|
||||
GetFramework().GetBookmark(indexPath.row, bm);
|
||||
Bookmark const * bm = m_category->GetBookmark(indexPath.row);
|
||||
|
||||
cell.featureName.text = [NSString stringWithUTF8String:bm.GetName().c_str()];
|
||||
cell.featureName.text = [NSString stringWithUTF8String:bm->GetName().c_str()];
|
||||
cell.featureCountry.text = [NSString stringWithUTF8String:"Region"];
|
||||
cell.featureType.text = [NSString stringWithUTF8String:"Type"];
|
||||
cell.featureDistance.text = [NSString stringWithFormat:@"%f", 0.0];
|
||||
|
@ -100,12 +93,10 @@
|
|||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Framework & f = GetFramework();
|
||||
if (indexPath.row < (NSInteger)f.BookmarksCount())
|
||||
if (indexPath.row < (NSInteger)m_category->GetBookmarksCount())
|
||||
{
|
||||
Bookmark bm;
|
||||
f.GetBookmark(indexPath.row, bm);
|
||||
f.ShowRect(bm.GetViewport());
|
||||
Bookmark const * bm = m_category->GetBookmark(indexPath.row);
|
||||
GetFramework().ShowRect(bm->GetViewport());
|
||||
|
||||
// Same as "Close".
|
||||
[self dismissModalViewControllerAnimated:YES];
|
||||
|
@ -125,7 +116,7 @@
|
|||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete)
|
||||
{
|
||||
GetFramework().RemoveBookmark(indexPath.row);
|
||||
m_category->RemoveBookmark(indexPath.row);
|
||||
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -492,7 +492,6 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
|
|||
{
|
||||
// Zoom to the feature
|
||||
case search::Result::RESULT_FEATURE:
|
||||
m_framework->AddBookmark(res.GetFeatureCenter(), res.GetString());
|
||||
m_framework->ShowSearchResult(res);
|
||||
|
||||
// Same as "Close" button but do not disable placemark
|
||||
|
|
201
map/bookmark.cpp
Normal file
201
map/bookmark.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
#include "bookmark.hpp"
|
||||
|
||||
#include "../indexer/mercator.hpp"
|
||||
|
||||
#include "../coding/parse_xml.hpp" // LoadFromKML
|
||||
|
||||
#include "../base/stl_add.hpp"
|
||||
#include "../base/string_utils.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp> // boost::trim
|
||||
|
||||
|
||||
void BookmarkCategory::AddBookmark(Bookmark const & bm)
|
||||
{
|
||||
m_bookmarks.push_back(new Bookmark(bm));
|
||||
}
|
||||
|
||||
BookmarkCategory::~BookmarkCategory()
|
||||
{
|
||||
ClearBookmarks();
|
||||
}
|
||||
|
||||
void BookmarkCategory::ClearBookmarks()
|
||||
{
|
||||
for_each(m_bookmarks.begin(), m_bookmarks.end(), DeleteFunctor());
|
||||
m_bookmarks.clear();
|
||||
}
|
||||
|
||||
void BookmarkCategory::RemoveBookmark(size_t index)
|
||||
{
|
||||
if (index < m_bookmarks.size())
|
||||
m_bookmarks.erase(m_bookmarks.begin() + index);
|
||||
}
|
||||
|
||||
Bookmark const * BookmarkCategory::GetBookmark(size_t index) const
|
||||
{
|
||||
return (index < m_bookmarks.size() ? m_bookmarks[index] : 0);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class KMLParser
|
||||
{
|
||||
BookmarkCategory & m_category;
|
||||
|
||||
int m_level;
|
||||
|
||||
string m_name;
|
||||
m2::PointD m_org;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_name.clear();
|
||||
m_org = m2::PointD(-1000, -1000);
|
||||
}
|
||||
|
||||
void SetOrigin(string const & s)
|
||||
{
|
||||
// order in string is: lon, lat, z
|
||||
|
||||
strings::SimpleTokenizer iter(s, ", ");
|
||||
if (iter)
|
||||
{
|
||||
double lon;
|
||||
if (strings::to_double(*iter, lon) && MercatorBounds::ValidLon(lon) && ++iter)
|
||||
{
|
||||
double lat;
|
||||
if (strings::to_double(*iter, lat) && MercatorBounds::ValidLat(lat))
|
||||
m_org = m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return (!m_name.empty() &&
|
||||
MercatorBounds::ValidX(m_org.x) && MercatorBounds::ValidY(m_org.y));
|
||||
}
|
||||
|
||||
public:
|
||||
KMLParser(BookmarkCategory & cat) : m_category(cat), m_level(0)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool Push(string const & name)
|
||||
{
|
||||
switch (m_level)
|
||||
{
|
||||
case 0:
|
||||
if (name != "kml") return false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (name != "Document") return false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (name != "Placemark") return false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (name != "Point" && name != "name") return false;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (name != "coordinates") return false;
|
||||
}
|
||||
|
||||
++m_level;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddAttr(string const &, string const &) {}
|
||||
|
||||
void Pop(string const &)
|
||||
{
|
||||
--m_level;
|
||||
|
||||
if (m_level == 2 && IsValid())
|
||||
{
|
||||
m_category.AddBookmark(Bookmark(m_org, m_name));
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
class IsSpace
|
||||
{
|
||||
public:
|
||||
bool operator() (char c) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void BookmarkCategory::LoadFromKML(ReaderPtr<Reader> const & reader)
|
||||
{
|
||||
ReaderSource<ReaderPtr<Reader> > src(reader);
|
||||
KMLParser parser(*this);
|
||||
ParseXML(src, parser, true);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * kmlHeader =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<kml xmlns=\"http://earth.google.com/kml/2.2\">\n"
|
||||
"<Document>\n"
|
||||
" <name>MapsWithMe</name>\n";
|
||||
|
||||
char const * kmlFooter =
|
||||
"</Document>\n"
|
||||
"</kml>\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 BookmarkCategory::SaveToKML(ostream & s)
|
||||
{
|
||||
s << kmlHeader;
|
||||
|
||||
for (size_t i = 0; i < m_bookmarks.size(); ++i)
|
||||
{
|
||||
Bookmark const * bm = m_bookmarks[i];
|
||||
s << " <Placemark>\n"
|
||||
<< " <name>" << bm->GetName() << "</name>\n"
|
||||
<< " <Point>\n"
|
||||
<< " <coordinates>" << PointToString(bm->GetOrg()) << "</coordinates>\n"
|
||||
<< " </Point>\n"
|
||||
<< " </Placemark>\n";
|
||||
}
|
||||
|
||||
s << kmlFooter;
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "../coding/reader.hpp"
|
||||
|
||||
#include "../geometry/point2d.hpp"
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
#include "../std/string.hpp"
|
||||
#include "../std/noncopyable.hpp"
|
||||
#include "../std/iostream.hpp"
|
||||
|
||||
|
||||
class Bookmark
|
||||
|
@ -21,3 +26,28 @@ public:
|
|||
string const & GetName() const { return m_name; }
|
||||
m2::RectD GetViewport() const { return m2::RectD(m_org, m_org); }
|
||||
};
|
||||
|
||||
class BookmarkCategory : private noncopyable
|
||||
{
|
||||
string m_name;
|
||||
vector<Bookmark *> m_bookmarks;
|
||||
bool m_visible;
|
||||
|
||||
public:
|
||||
BookmarkCategory(string const & name) : m_name(name), m_visible(true) {}
|
||||
~BookmarkCategory();
|
||||
|
||||
void ClearBookmarks();
|
||||
|
||||
void AddBookmark(Bookmark const & bm);
|
||||
|
||||
bool IsVisible() const { return m_visible; }
|
||||
string GetName() const { return m_name; }
|
||||
|
||||
inline size_t GetBookmarksCount() const { return m_bookmarks.size(); }
|
||||
Bookmark const * GetBookmark(size_t index) const;
|
||||
void RemoveBookmark(size_t index);
|
||||
|
||||
void LoadFromKML(ReaderPtr<Reader> const & reader);
|
||||
void SaveToKML(ostream & s);
|
||||
};
|
||||
|
|
|
@ -43,8 +43,13 @@ int FeaturesFetcher::AddMap(string const & file)
|
|||
}
|
||||
catch (Reader::Exception const & e)
|
||||
{
|
||||
LOG(LERROR, ("Data file adding error: ", e.what()));
|
||||
LOG(LERROR, ("IO error while adding ", file, " map. ", e.what()));
|
||||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
LOG(LERROR, ("Can't find map ", file, ". ", e.what()));
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,12 @@
|
|||
#include "../indexer/feature.hpp"
|
||||
#include "../indexer/scales.hpp"
|
||||
|
||||
#include "../coding/parse_xml.hpp" // LoadFromKML
|
||||
|
||||
#include "../base/math.hpp"
|
||||
#include "../base/string_utils.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
#include "../std/target_os.hpp"
|
||||
#include "../std/vector.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
||||
void Framework::AddMap(string const & file)
|
||||
{
|
||||
|
@ -147,18 +142,12 @@ Framework::Framework()
|
|||
// is connected/disconnected
|
||||
GetLocalMaps(maps);
|
||||
#endif
|
||||
|
||||
// Remove duplicate maps if they're both present in resources and in WritableDir
|
||||
sort(maps.begin(), maps.end());
|
||||
maps.erase(unique(maps.begin(), maps.end()), maps.end());
|
||||
try
|
||||
{
|
||||
for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1));
|
||||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
LOG(LERROR, ("Can't add map: ", e.what()));
|
||||
}
|
||||
|
||||
for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1));
|
||||
|
||||
m_storage.Init(bind(&Framework::AddMap, this, _1),
|
||||
bind(&Framework::RemoveMap, this, _1),
|
||||
|
@ -167,7 +156,9 @@ Framework::Framework()
|
|||
}
|
||||
|
||||
Framework::~Framework()
|
||||
{}
|
||||
{
|
||||
ClearBookmarks();
|
||||
}
|
||||
|
||||
void Framework::AddLocalMaps()
|
||||
{
|
||||
|
@ -191,224 +182,83 @@ void Framework::RemoveLocalMaps()
|
|||
m_model.RemoveAllCountries();
|
||||
}
|
||||
|
||||
void Framework::AddBookmark(m2::PointD const & pt, string const & name)
|
||||
void Framework::AddBookmark(string const & category, Bookmark const & bm)
|
||||
{
|
||||
m_bookmarks.push_back(Bookmark(pt, name));
|
||||
GetBmCategory(category)->AddBookmark(bm);
|
||||
}
|
||||
|
||||
void Framework::GetBookmark(size_t index, Bookmark & bm) const
|
||||
namespace
|
||||
{
|
||||
ASSERT_LESS(index, BookmarksCount(), ());
|
||||
|
||||
list<Bookmark>::const_iterator it = m_bookmarks.begin();
|
||||
advance(it, index); // not so fast ...
|
||||
|
||||
bm = *it;
|
||||
class EqualCategoryName
|
||||
{
|
||||
string const & m_name;
|
||||
public:
|
||||
EqualCategoryName(string const & name) : m_name(name) {}
|
||||
bool operator() (BookmarkCategory const * cat) const
|
||||
{
|
||||
return (cat->GetName() == m_name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
size_t Framework::GetBookmark(m2::PointD pt, Bookmark & bm) const
|
||||
BookmarkCategory * Framework::GetBmCategory(size_t index) const
|
||||
{
|
||||
return (index < m_bookmarks.size() ? m_bookmarks[index] : 0);
|
||||
}
|
||||
|
||||
BookmarkCategory * Framework::GetBmCategory(string const & name)
|
||||
{
|
||||
vector<BookmarkCategory *>::iterator i =
|
||||
find_if(m_bookmarks.begin(), m_bookmarks.end(), EqualCategoryName(name));
|
||||
|
||||
if (i != m_bookmarks.end())
|
||||
return (*i);
|
||||
else
|
||||
{
|
||||
BookmarkCategory * cat = new BookmarkCategory(name);
|
||||
m_bookmarks.push_back(cat);
|
||||
return cat;
|
||||
}
|
||||
}
|
||||
|
||||
Bookmark const * Framework::GetBookmark(m2::PointD pt) const
|
||||
{
|
||||
// Get the global rect of touching area.
|
||||
int const sm = 20 * GetPlatform().VisualScale();
|
||||
m2::RectD rect(PtoG(m2::PointD(pt.x - sm, pt.y - sm)), PtoG(m2::PointD(pt.x + sm, pt.y + sm)));
|
||||
|
||||
size_t bestInd = static_cast<size_t>(-1);
|
||||
Bookmark const * ret = 0;
|
||||
double minD = numeric_limits<double>::max();
|
||||
|
||||
size_t ind = 0;
|
||||
for (list<Bookmark>::const_iterator it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it, ++ind)
|
||||
for (size_t i = 0; i < m_bookmarks.size(); ++i)
|
||||
{
|
||||
if (rect.IsPointInside(it->GetOrg()))
|
||||
size_t const count = m_bookmarks[i]->GetBookmarksCount();
|
||||
for (size_t j = 0; j < count; ++j)
|
||||
{
|
||||
double const d = rect.Center().SquareLength(it->GetOrg());
|
||||
if (d < minD)
|
||||
Bookmark const * bm = m_bookmarks[i]->GetBookmark(j);
|
||||
m2::PointD const pt = bm->GetOrg();
|
||||
|
||||
if (rect.IsPointInside(pt))
|
||||
{
|
||||
bm = *it;
|
||||
bestInd = ind;
|
||||
double const d = rect.Center().SquareLength(pt);
|
||||
if (d < minD)
|
||||
{
|
||||
ret = bm;
|
||||
minD = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestInd;
|
||||
}
|
||||
|
||||
void Framework::RemoveBookmark(size_t index)
|
||||
{
|
||||
if (index >= m_bookmarks.size())
|
||||
{
|
||||
LOG(LWARNING, ("Trying to delete invalid bookmark with index", index));
|
||||
return;
|
||||
}
|
||||
list<Bookmark>::iterator it = m_bookmarks.begin();
|
||||
advance(it, index); // not so fast ...
|
||||
m_bookmarks.erase(it);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Framework::ClearBookmarks()
|
||||
{
|
||||
for_each(m_bookmarks.begin(), m_bookmarks.end(), DeleteFunctor());
|
||||
m_bookmarks.clear();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class KMLParser
|
||||
{
|
||||
Framework & m_framework;
|
||||
|
||||
int m_level;
|
||||
|
||||
string m_name;
|
||||
m2::PointD m_org;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_name.clear();
|
||||
m_org = m2::PointD(-1000, -1000);
|
||||
}
|
||||
|
||||
void SetOrigin(string const & s)
|
||||
{
|
||||
// order in string is: lon, lat, z
|
||||
|
||||
strings::SimpleTokenizer iter(s, ", ");
|
||||
if (iter)
|
||||
{
|
||||
double lon;
|
||||
if (strings::to_double(*iter, lon) && MercatorBounds::ValidLon(lon) && ++iter)
|
||||
{
|
||||
double lat;
|
||||
if (strings::to_double(*iter, lat) && MercatorBounds::ValidLat(lat))
|
||||
m_org = m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return (!m_name.empty() &&
|
||||
MercatorBounds::ValidX(m_org.x) && MercatorBounds::ValidY(m_org.y));
|
||||
}
|
||||
|
||||
public:
|
||||
KMLParser(Framework & f) : m_framework(f), m_level(0)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool Push(string const & name)
|
||||
{
|
||||
switch (m_level)
|
||||
{
|
||||
case 0:
|
||||
if (name != "kml") return false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (name != "Document") return false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (name != "Placemark") return false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (name != "Point" && name != "name") return false;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (name != "coordinates") return false;
|
||||
}
|
||||
|
||||
++m_level;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddAttr(string const &, string const &) {}
|
||||
|
||||
void Pop(string const &)
|
||||
{
|
||||
--m_level;
|
||||
|
||||
if (m_level == 2 && IsValid())
|
||||
{
|
||||
m_framework.AddBookmark(m_org, m_name);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
class IsSpace
|
||||
{
|
||||
public:
|
||||
bool operator() (char c) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Framework::LoadFromKML(ReaderPtr<Reader> const & reader)
|
||||
{
|
||||
ReaderSource<ReaderPtr<Reader> > src(reader);
|
||||
KMLParser parser(*this);
|
||||
ParseXML(src, parser, true);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * kmlHeader =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<kml xmlns=\"http://earth.google.com/kml/2.2\">\n"
|
||||
"<Document>\n"
|
||||
" <name>MapsWithMe</name>\n";
|
||||
|
||||
char const * kmlFooter =
|
||||
"</Document>\n"
|
||||
"</kml>\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<Bookmark>::const_iterator i = m_bookmarks.begin(); i != m_bookmarks.end(); ++i)
|
||||
{
|
||||
s << " <Placemark>\n"
|
||||
<< " <name>" << i->GetName() << "</name>\n"
|
||||
<< " <Point>\n"
|
||||
<< " <coordinates>" << PointToString(i->GetOrg()) << "</coordinates>\n"
|
||||
<< " </Point>\n"
|
||||
<< " </Placemark>\n";
|
||||
}
|
||||
|
||||
s << kmlFooter;
|
||||
}
|
||||
|
||||
void Framework::GetLocalMaps(vector<string> & outMaps)
|
||||
{
|
||||
Platform & pl = GetPlatform();
|
||||
|
@ -620,11 +470,17 @@ void Framework::DrawAdditionalInfo(shared_ptr<PaintEvent> const & e)
|
|||
if (m_drawPlacemark)
|
||||
m_informationDisplay.drawPlacemark(pDrawer, "placemark", m_navigator.GtoP(m_placemark));
|
||||
|
||||
for (list<Bookmark>::const_iterator i = m_bookmarks.begin(); i != m_bookmarks.end(); ++i)
|
||||
{
|
||||
/// @todo Pass different symbol.
|
||||
m_informationDisplay.drawPlacemark(pDrawer, "placemark", m_navigator.GtoP(i->GetOrg()));
|
||||
}
|
||||
for (size_t i = 0; i < m_bookmarks.size(); ++i)
|
||||
if (m_bookmarks[i]->IsVisible())
|
||||
{
|
||||
size_t const count = m_bookmarks[i]->GetBookmarksCount();
|
||||
for (size_t j = 0; j < count; ++j)
|
||||
{
|
||||
Bookmark const * bm = m_bookmarks[i]->GetBookmark(j);
|
||||
/// @todo Pass different symbol.
|
||||
m_informationDisplay.drawPlacemark(pDrawer, "placemark", m_navigator.GtoP(bm->GetOrg()));
|
||||
}
|
||||
}
|
||||
|
||||
pDrawer->screen()->endFrame();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
|||
model::FeaturesFetcher m_model;
|
||||
Navigator m_navigator;
|
||||
|
||||
list<Bookmark> m_bookmarks;
|
||||
vector<BookmarkCategory *> m_bookmarks;
|
||||
|
||||
scoped_ptr<RenderPolicy> m_renderPolicy;
|
||||
bool m_hasPendingInvalidate, m_doForceUpdate, m_queryMaxScaleMode, m_drawPlacemark;
|
||||
|
@ -124,24 +124,23 @@ public:
|
|||
void AddLocalMaps();
|
||||
void RemoveLocalMaps();
|
||||
|
||||
void AddBookmark(m2::PointD const & pt, string const & name);
|
||||
inline size_t BookmarksCount() const { return m_bookmarks.size(); }
|
||||
void GetBookmark(size_t index, Bookmark & bm) const;
|
||||
void AddBookmark(string const & category, Bookmark const & bm);
|
||||
inline size_t GetBmCategoriesCount() const { return m_bookmarks.size(); }
|
||||
BookmarkCategory * GetBmCategory(size_t index) const;
|
||||
|
||||
/// Find or create new category by name.
|
||||
BookmarkCategory * GetBmCategory(string const & name);
|
||||
|
||||
/// Get bookmark by touch.
|
||||
/// @param[in] pixPt Coordinates of touch point in pixels.
|
||||
/// @return Index of bookmark (-1, if bookmark wasn't found).
|
||||
size_t GetBookmark(m2::PointD pixPt, Bookmark & bm) const;
|
||||
/// @return NULL If not biikmark near the point.
|
||||
Bookmark const * GetBookmark(m2::PointD pixPt) const;
|
||||
|
||||
void RemoveBookmark(size_t index);
|
||||
void ClearBookmarks();
|
||||
|
||||
inline m2::PointD PtoG(m2::PointD const & p) const { return m_navigator.PtoG(p); }
|
||||
inline m2::PointD GtoP(m2::PointD const & p) const { return m_navigator.GtoP(p); }
|
||||
|
||||
void LoadFromKML(ReaderPtr<Reader> const & reader);
|
||||
void SaveToKML(std::ostream & s);
|
||||
|
||||
storage::Storage & Storage() { return m_storage; }
|
||||
|
||||
void OnLocationStatusChanged(location::TLocationStatus newStatus);
|
||||
|
|
|
@ -90,6 +90,7 @@ SOURCES += \
|
|||
address_finder.cpp \
|
||||
tile_set.cpp \
|
||||
geourl_process.cpp \
|
||||
bookmark.cpp \
|
||||
|
||||
!iphone*:!bada*:!android* {
|
||||
HEADERS += qgl_render_context.hpp
|
||||
|
|
|
@ -54,18 +54,17 @@ char const * kmlString =
|
|||
"</Document>"
|
||||
"</kml>";
|
||||
|
||||
void CheckBookmarks(Framework const & fm)
|
||||
void CheckBookmarks(BookmarkCategory const & cat)
|
||||
{
|
||||
TEST_EQUAL(fm.BookmarksCount(), 3, ());
|
||||
TEST_EQUAL(cat.GetBookmarksCount(), 3, ());
|
||||
|
||||
Bookmark bm;
|
||||
fm.GetBookmark(0, bm);
|
||||
TEST_EQUAL(bm.GetName(), "Nebraska", ());
|
||||
fm.GetBookmark(1, bm);
|
||||
TEST_EQUAL(bm.GetName(), "Monongahela National Forest", ());
|
||||
Bookmark const * bm = cat.GetBookmark(0);
|
||||
TEST_EQUAL(bm->GetName(), "Nebraska", ());
|
||||
bm = cat.GetBookmark(1);
|
||||
TEST_EQUAL(bm->GetName(), "Monongahela National Forest", ());
|
||||
|
||||
fm.GetBookmark(2, bm);
|
||||
m2::PointD const org = bm.GetOrg();
|
||||
bm = cat.GetBookmark(2);
|
||||
m2::PointD const org = bm->GetOrg();
|
||||
TEST_ALMOST_EQUAL(MercatorBounds::XToLon(org.x), 27.566765, ());
|
||||
TEST_ALMOST_EQUAL(MercatorBounds::YToLat(org.y), 53.900047, ());
|
||||
}
|
||||
|
@ -73,31 +72,31 @@ char const * kmlString =
|
|||
|
||||
UNIT_TEST(Bookmarks_ImportKML)
|
||||
{
|
||||
Framework fm;
|
||||
fm.LoadFromKML(new MemReader(kmlString, strlen(kmlString)));
|
||||
BookmarkCategory cat("Default");
|
||||
cat.LoadFromKML(new MemReader(kmlString, strlen(kmlString)));
|
||||
|
||||
CheckBookmarks(fm);
|
||||
CheckBookmarks(cat);
|
||||
}
|
||||
|
||||
UNIT_TEST(Bookmarks_ExportKML)
|
||||
{
|
||||
Framework fm;
|
||||
fm.LoadFromKML(new MemReader(kmlString, strlen(kmlString)));
|
||||
BookmarkCategory cat("Default");
|
||||
cat.LoadFromKML(new MemReader(kmlString, strlen(kmlString)));
|
||||
|
||||
CheckBookmarks(fm);
|
||||
CheckBookmarks(cat);
|
||||
|
||||
{
|
||||
ofstream of("Bookmarks.kml");
|
||||
fm.SaveToKML(of);
|
||||
cat.SaveToKML(of);
|
||||
}
|
||||
|
||||
fm.ClearBookmarks();
|
||||
cat.ClearBookmarks();
|
||||
|
||||
TEST_EQUAL(fm.BookmarksCount(), 0, ());
|
||||
TEST_EQUAL(cat.GetBookmarksCount(), 0, ());
|
||||
|
||||
fm.LoadFromKML(new FileReader("Bookmarks.kml"));
|
||||
cat.LoadFromKML(new FileReader("Bookmarks.kml"));
|
||||
|
||||
CheckBookmarks(fm);
|
||||
CheckBookmarks(cat);
|
||||
}
|
||||
|
||||
UNIT_TEST(Bookmarks_Getting)
|
||||
|
@ -111,11 +110,14 @@ UNIT_TEST(Bookmarks_Getting)
|
|||
// This is not correct because Framework::OnSize doesn't work until SetRenderPolicy is called.
|
||||
//TEST(m2::AlmostEqual(m2::PointD(400, 200), pixC), (pixC));
|
||||
|
||||
fm.AddBookmark(m2::PointD(38, 20), "1");
|
||||
fm.AddBookmark(m2::PointD(41, 20), "2");
|
||||
fm.AddBookmark(m2::PointD(41, 40), "3");
|
||||
fm.AddBookmark("cat1", Bookmark(m2::PointD(38, 20), "1"));
|
||||
fm.AddBookmark("cat2", Bookmark(m2::PointD(41, 20), "2"));
|
||||
fm.AddBookmark("cat3", Bookmark(m2::PointD(41, 40), "3"));
|
||||
|
||||
Bookmark bm;
|
||||
TEST_EQUAL(fm.GetBookmark(pixC, bm), 1, ());
|
||||
TEST_EQUAL(bm.GetName(), "2", ());
|
||||
Bookmark const * bm = fm.GetBookmark(pixC);
|
||||
TEST(bm != 0, ());
|
||||
TEST_EQUAL(bm->GetName(), "2", ());
|
||||
|
||||
TEST(fm.GetBookmark(m2::PointD(0, 0)) == 0, ());
|
||||
TEST(fm.GetBookmark(m2::PointD(800, 400)) == 0, ());
|
||||
}
|
||||
|
|
|
@ -138,7 +138,8 @@ void SearchPanel::OnSearchResult(ResultsT * res, int queryId)
|
|||
|
||||
if (e.GetResultType() == ResultT::RESULT_FEATURE)
|
||||
{
|
||||
frm.AddBookmark(e.GetFeatureCenter(), e.GetString());
|
||||
// For debug purposes: add bookmarks for search results
|
||||
frm.AddBookmark("Search", Bookmark(e.GetFeatureCenter(), e.GetString()));
|
||||
|
||||
m_pTable->setItem(rowCount, 0,
|
||||
create_item(QString::fromUtf8(e.GetFeatureType())));
|
||||
|
|
Loading…
Add table
Reference in a new issue